Add token lookup for faucet gift callback

This commit is contained in:
nolash 2021-04-14 19:21:35 +02:00
parent 5f99048154
commit bb930ce148
Signed by untrusted user who does not match committer: lash
GPG Key ID: 21D2E7BB88C2A746
5 changed files with 77 additions and 62 deletions

View File

@ -9,7 +9,12 @@ from chainlib.eth.address import to_checksum_address
from chainlib.eth.error import RequestMismatchException from chainlib.eth.error import RequestMismatchException
from chainlib.eth.constant import ZERO_ADDRESS from chainlib.eth.constant import ZERO_ADDRESS
from chainlib.eth.erc20 import ERC20 from chainlib.eth.erc20 import ERC20
from hexathon import strip_0x from hexathon import (
strip_0x,
add_0x,
)
# TODO: use sarafu_Faucet for both when inheritance has been implemented
from erc20_single_shot_faucet import SingleShotFaucet
from sarafu_faucet import MinterFaucet as Faucet from sarafu_faucet import MinterFaucet as Faucet
# local imports # local imports
@ -19,41 +24,6 @@ from cic_eth.eth.meta import ExtendedTx
logg = logging.getLogger().getChild(__name__) logg = logging.getLogger().getChild(__name__)
def parse_transfer(tx):
if not tx.payload:
return (None, None)
r = ERC20.parse_transfer_request(tx.payload)
transfer_data = {}
transfer_data['to'] = r[0]
transfer_data['value'] = r[1]
transfer_data['from'] = tx.outputs[0]
transfer_data['token_address'] = tx.inputs[0]
return ('transfer', transfer_data)
def parse_transferfrom(tx):
if not tx.payload:
return (None, None)
r = ERC20.parse_transfer_from_request(tx.payload)
transfer_data = {}
transfer_data['from'] = r[0]
transfer_data['to'] = r[1]
transfer_data['value'] = r[2]
transfer_data['token_address'] = tx.inputs[0]
return ('transferfrom', transfer_data)
def parse_giftto(tx):
if not tx.payload:
return (None, None)
r = Faucet.parse_give_to_request(tx.payload)
transfer_data = {}
transfer_data['to'] = r[0]
transfer_data['value'] = tx.value
transfer_data['from'] = tx.outputs[0]
transfer_data['token_address'] = tx.inputs[0]
return ('tokengift', transfer_data)
class CallbackFilter(SyncFilter): class CallbackFilter(SyncFilter):
@ -66,6 +36,49 @@ class CallbackFilter(SyncFilter):
self.caller_address = caller_address self.caller_address = caller_address
def parse_transfer(self, tx, conn):
if not tx.payload:
return (None, None)
r = ERC20.parse_transfer_request(tx.payload)
transfer_data = {}
transfer_data['to'] = r[0]
transfer_data['value'] = r[1]
transfer_data['from'] = tx.outputs[0]
transfer_data['token_address'] = tx.inputs[0]
return ('transfer', transfer_data)
def parse_transferfrom(self, tx, conn):
if not tx.payload:
return (None, None)
r = ERC20.parse_transfer_from_request(tx.payload)
transfer_data = {}
transfer_data['from'] = r[0]
transfer_data['to'] = r[1]
transfer_data['value'] = r[2]
transfer_data['token_address'] = tx.inputs[0]
return ('transferfrom', transfer_data)
def parse_giftto(self, tx, conn):
if not tx.payload:
return (None, None)
r = Faucet.parse_give_to_request(tx.payload)
transfer_data = {}
transfer_data['to'] = r[0]
transfer_data['value'] = tx.value
transfer_data['from'] = tx.outputs[0]
#transfer_data['token_address'] = tx.inputs[0]
faucet_contract = tx.inputs[0]
c = SingleShotFaucet(self.chain_spec)
o = c.token(faucet_contract, sender_address=self.caller_address)
r = conn.do(o)
transfer_data['token_address'] = add_0x(c.parse_token(r))
return ('tokengift', transfer_data)
def call_back(self, transfer_type, result): def call_back(self, transfer_type, result):
logg.debug('result {}'.format(result)) logg.debug('result {}'.format(result))
s = celery.signature( s = celery.signature(
@ -92,7 +105,7 @@ class CallbackFilter(SyncFilter):
return s return s
def parse_data(self, tx): def parse_data(self, tx, conn):
transfer_type = None transfer_type = None
transfer_data = None transfer_data = None
# TODO: what's with the mix of attributes and dict keys # TODO: what's with the mix of attributes and dict keys
@ -101,13 +114,13 @@ class CallbackFilter(SyncFilter):
logg.debug('tx status {}'.format(tx.status)) logg.debug('tx status {}'.format(tx.status))
for parser in [ for parser in [
parse_transfer, self.parse_transfer,
parse_transferfrom, self.parse_transferfrom,
parse_giftto, self.parse_giftto,
]: ]:
try: try:
if tx: if tx:
(transfer_type, transfer_data) = parser(tx) (transfer_type, transfer_data) = parser(tx, conn)
if transfer_type == None: if transfer_type == None:
continue continue
else: else:
@ -127,11 +140,12 @@ class CallbackFilter(SyncFilter):
def filter(self, conn, block, tx, db_session=None): def filter(self, conn, block, tx, db_session=None):
transfer_data = None transfer_data = None
transfer_type = None transfer_type = None
try: (transfer_type, transfer_data) = self.parse_data(tx, conn)
(transfer_type, transfer_data) = self.parse_data(tx) # try:
except TypeError: # (transfer_type, transfer_data) = self.parse_data(tx, conn)
logg.debug('invalid method data length for tx {}'.format(tx.hash)) # except TypeError:
return # logg.debug('invalid method data length for tx {}'.format(tx.hash))
# return
if len(tx.payload) < 8: if len(tx.payload) < 8:
logg.debug('callbacks filter data length not sufficient for method signature in tx {}, skipping'.format(tx.hash)) logg.debug('callbacks filter data length not sufficient for method signature in tx {}, skipping'.format(tx.hash))

View File

@ -1,4 +1,4 @@
cic-base~=0.1.2a71 cic-base~=0.1.2a75
celery==4.4.7 celery==4.4.7
crypto-dev-signer~=0.4.14b2 crypto-dev-signer~=0.4.14b2
confini~=0.3.6rc3 confini~=0.3.6rc3
@ -21,5 +21,5 @@ chainsyncer[sql]~=0.0.2a1
chainqueue~=0.0.1a7 chainqueue~=0.0.1a7
pysha3==1.0.2 pysha3==1.0.2
coincurve==15.0.0 coincurve==15.0.0
sarafu-faucet==0.0.2a25 sarafu-faucet==0.0.2a27
potaahto~=0.0.1a1 potaahto~=0.0.1a1

View File

@ -21,12 +21,7 @@ from potaahto.symbols import snake_and_camel
from hexathon import add_0x from hexathon import add_0x
# local imports # local imports
from cic_eth.runnable.daemons.filters.callback import ( from cic_eth.runnable.daemons.filters.callback import CallbackFilter
parse_transfer,
parse_transferfrom,
parse_giftto,
CallbackFilter,
)
logg = logging.getLogger() logg = logging.getLogger()
@ -40,6 +35,7 @@ def test_transfer_tx(
foo_token, foo_token,
agent_roles, agent_roles,
token_roles, token_roles,
contract_roles,
celery_session_worker, celery_session_worker,
): ):
@ -64,7 +60,8 @@ def test_transfer_tx(
rcpt = snake_and_camel(r) rcpt = snake_and_camel(r)
tx.apply_receipt(rcpt) tx.apply_receipt(rcpt)
(transfer_type, transfer_data) = parse_transfer(tx) fltr = CallbackFilter(default_chain_spec, None, None, caller_address=contract_roles['CONTRACT_DEPLOYER'])
(transfer_type, transfer_data) = fltr.parse_transfer(tx, eth_rpc)
assert transfer_type == 'transfer' assert transfer_type == 'transfer'
@ -78,6 +75,7 @@ def test_transfer_from_tx(
foo_token, foo_token,
agent_roles, agent_roles,
token_roles, token_roles,
contract_roles,
celery_session_worker, celery_session_worker,
): ):
@ -110,12 +108,12 @@ def test_transfer_from_tx(
rcpt = snake_and_camel(r) rcpt = snake_and_camel(r)
tx.apply_receipt(rcpt) tx.apply_receipt(rcpt)
(transfer_type, transfer_data) = parse_transferfrom(tx) fltr = CallbackFilter(default_chain_spec, None, None, caller_address=contract_roles['CONTRACT_DEPLOYER'])
(transfer_type, transfer_data) = fltr.parse_transferfrom(tx, eth_rpc)
assert transfer_type == 'transferfrom' assert transfer_type == 'transferfrom'
@pytest.mark.skip()
def test_faucet_gift_to_tx( def test_faucet_gift_to_tx(
default_chain_spec, default_chain_spec,
init_database, init_database,
@ -157,9 +155,11 @@ def test_faucet_gift_to_tx(
rcpt = snake_and_camel(r) rcpt = snake_and_camel(r)
tx.apply_receipt(rcpt) tx.apply_receipt(rcpt)
(transfer_type, transfer_data) = parse_giftto(tx) fltr = CallbackFilter(default_chain_spec, None, None, caller_address=contract_roles['CONTRACT_DEPLOYER'])
(transfer_type, transfer_data) = fltr.parse_giftto(tx, eth_rpc)
assert transfer_type == 'tokengift' assert transfer_type == 'tokengift'
assert transfer_data['token_address'] == foo_token
def test_callback_filter( def test_callback_filter(
@ -220,3 +220,4 @@ def test_callback_filter(
fltr.filter(eth_rpc, mockblock, tx, init_database) fltr.filter(eth_rpc, mockblock, tx, init_database)
assert mock.results.get('transfer') != None assert mock.results.get('transfer') != None
assert mock.results['transfer']['destination_token'] == foo_token

View File

@ -57,9 +57,9 @@ WORKDIR /home/grassroots
USER grassroots USER grassroots
ARG pip_extra_index_url=https://pip.grassrootseconomics.net:8433 ARG pip_extra_index_url=https://pip.grassrootseconomics.net:8433
ARG cic_base_version=0.1.2a72 ARG cic_base_version=0.1.2a75
ARG cic_eth_version=0.11.0b5 ARG cic_eth_version=0.11.0b5
ARG sarafu_faucet_version=0.0.2a25 ARG sarafu_faucet_version=0.0.2a27
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 \

View File

@ -1,5 +1,5 @@
cic-base[full]==0.1.2a72 cic-base[full]==0.1.2a75
sarafu-faucet==0.0.2a25 sarafu-faucet==0.0.2a27
cic-eth==0.11.0b5 cic-eth==0.11.0b5
cic-types==0.1.0a10 cic-types==0.1.0a10
crypto-dev-signer==0.4.14b2 crypto-dev-signer==0.4.14b2