WIP token info proof verify

This commit is contained in:
nolash 2021-10-09 00:48:20 +02:00
parent 7e2857d1e7
commit f648d3ee68
Signed by untrusted user who does not match committer: lash
GPG Key ID: 21D2E7BB88C2A746
4 changed files with 115 additions and 75 deletions

View File

@ -61,17 +61,17 @@ class Api(ApiBase):
queue=self.queue, queue=self.queue,
) )
s_token_verify = celery.signature( # s_token_verify = celery.signature(
'cic_eth.eth.erc20.verify_token_info', # 'cic_eth.eth.erc20.verify_token_info',
[ # [
chain_spec_dict, # chain_spec_dict,
], # ],
queue=self.queue, # queue=self.queue,
) # )
#s_token.link(s_token_verify)
s_token_resolve.link(s_token) s_token_resolve.link(s_token)
s_token.link(s_token_verify)
if self.callback_param != None: if self.callback_param != None:
s_token_verify.link(self.callback_success) s_token.link(self.callback_success)
return s_token_resolve.apply_async() return s_token_resolve.apply_async()

View File

@ -483,7 +483,11 @@ def token_info(self, tokens, chain_spec_dict, proofs=[]):
rpc = RPCConnection.connect(chain_spec, 'default') rpc = RPCConnection.connect(chain_spec, 'default')
result_data = [] result_data = []
queue = self.request.delivery_info.get('routing_key')
i = 0 i = 0
s_group = []
for token in tokens: for token in tokens:
token_chain_object = ERC20Token(chain_spec, rpc, add_0x(token['address'])) token_chain_object = ERC20Token(chain_spec, rpc, add_0x(token['address']))
token_chain_object.load(rpc) token_chain_object.load(rpc)
@ -497,39 +501,26 @@ def token_info(self, tokens, chain_spec_dict, proofs=[]):
'decimals': token_chain_object.decimals, 'decimals': token_chain_object.decimals,
'name': token_chain_object.name, 'name': token_chain_object.name,
'symbol': token_chain_object.symbol, 'symbol': token_chain_object.symbol,
'address': token_chain_object.address, 'address': tx_normalize.executable_address(token_chain_object.address),
'proofs': token_proofs,
} }
result_data.append(token_data) result_data.append(token_data)
s = celery.signature(
'cic_eth.eth.trust.verify_proofs',
[
token,
token_chain_object.address,
token_proofs,
chain_spec_dict,
],
queue=queue,
)
s_group.append(s)
i += 1 i += 1
return result_data celery.group(s_group)()
#return result_data
@celery_app.task(bind=True, base=BaseTask)
def verify_token_info(self, tokens, chain_spec_dict):
subjects = []
proofs = []
for token in tokens:
subjects.append(token['address'])
proofs.append(token['proofs'])
queue = self.request.delivery_info.get('routing_key')
s = celery.signature(
'cic_eth.eth.trust.verify_proofs',
[
tokens,
chain_spec_dict,
subjects,
proofs,
],
queue=queue,
)
s.apply_async()
return tokens
@celery_app.task(bind=True, base=BaseTask) @celery_app.task(bind=True, base=BaseTask)

View File

@ -8,6 +8,7 @@ from chainlib.connection import RPCConnection
from chainlib.chain import ChainSpec from chainlib.chain import ChainSpec
from cic_eth.db.models.role import AccountRole from cic_eth.db.models.role import AccountRole
from cic_eth_registry import CICRegistry from cic_eth_registry import CICRegistry
from hexathon import strip_0x
# local imports # local imports
from cic_eth.task import BaseTask from cic_eth.task import BaseTask
@ -16,21 +17,17 @@ from cic_eth.error import TrustError
celery_app = celery.current_app celery_app = celery.current_app
logg = logging.getLogger() logg = logging.getLogger()
@celery_app.task(bind=True, base=BaseTask)
def collect(self, collection):
logg.debug('collect {}'.format(collection))
return collection
@celery_app.task(bind=True, base=BaseTask) @celery_app.task(bind=True, base=BaseTask)
def verify_proofs(self, chained_input, chain_spec_dict, subjects, proofs): def verify_proof(self, chained_input, proof, subject, chain_spec_dict):
if not isinstance(subjects, list):
raise ValueError('subjects argument must be list')
if isinstance(proofs, str):
proofs = [[proofs]]
elif not isinstance(proofs, list):
raise ValueError('proofs argument must be string or list')
if len(proofs) != 1 and len(subjects) != len(proofs):
raise ValueError('proof argument must be single proof or one proof input per subject')
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
rpc = RPCConnection.connect(chain_spec, 'default') rpc = RPCConnection.connect(chain_spec, 'default')
declarator = Declarator(chain_spec)
session = self.create_session() session = self.create_session()
sender_address = AccountRole.get_address('DEFAULT', session) sender_address = AccountRole.get_address('DEFAULT', session)
@ -38,32 +35,67 @@ def verify_proofs(self, chained_input, chain_spec_dict, subjects, proofs):
registry = CICRegistry(chain_spec, rpc) registry = CICRegistry(chain_spec, rpc)
declarator_address = registry.by_name('AddressDeclarator', sender_address=sender_address) declarator_address = registry.by_name('AddressDeclarator', sender_address=sender_address)
declarator = Declarator(chain_spec)
logg.debug('foo {}'.format(proof))
proof = strip_0x(proof)
logg.debug('proof is {}'.format(proof))
proof_count = 0
for trusted_address in self.trusted_addresses:
o = declarator.declaration(declarator_address, trusted_address, subject, sender_address=sender_address)
r = rpc.do(o)
declarations = declarator.parse_declaration(r)
logg.debug('comparing proof {} with declarations for {} by {}: {}'.format(proof, subject, trusted_address, declarations))
for declaration in declarations:
declaration = strip_0x(declaration)
if declaration == proof:
logg.debug('have token proof {} match for trusted address {}'.format(declaration, trusted_address))
proof_count += 1
logg.debug('proof count {}'.format(proof_count))
if proof_count == 0:
logg.debug('error {}'.format(proof_count))
raise TrustError('no trusted records found for subject {} proof {}'.format(subject, proof))
return chained_input
@celery_app.task(bind=True, base=BaseTask)
def verify_proofs(self, chained_input, subject, proofs, chain_spec_dict):
if isinstance(proofs, str):
proofs = [[proofs]]
elif not isinstance(proofs, list):
raise ValueError('proofs argument must be string or list')
i = 0 i = 0
for proof in proofs: for proof in proofs:
if not isinstance(proof, list): if not isinstance(proof, list):
proofs[i] = [proof]
logg.debug('proof entry {} is not a list'.format(i)) logg.debug('proof entry {} is not a list'.format(i))
i += 1 i += 1
i = 0 queue = self.request.delivery_info.get('routing_key')
for subject in subjects:
for trusted_address in self.trusted_addresses:
proof_count = {}
for proof in proofs[i]:
o = declarator.declaration(declarator_address, trusted_address, subject, sender_address=sender_address)
r = rpc.do(o)
declarations = declarator.parse_declaration(r)
logg.debug('comparing proof {} with declarations for {} by {}: {}'.format(proofs, subject, trusted_address, declarations))
for declaration in declarations:
if declaration == proof:
logg.debug('have token proof {} match for trusted address {}'.format(declaration, trusted_address))
if proof_count.get(proof) == None:
proof_count[proof] = 0
proof_count[proof] += 1
for k in proof_count.keys(): s_group = []
if proof_count[k] == 0: for proof in proofs:
raise TrustError('no proof found for token {}'.format(subject)) logg.debug('proof before {}'.format(proof))
if isinstance(proof, str):
proof = [proof]
for single_proof in proof:
logg.debug('proof after {}'.format(single_proof))
s = celery.signature(
'cic_eth.eth.trust.verify_proof',
[
chained_input,
single_proof,
subject,
chain_spec_dict,
],
queue=queue,
)
#s_group.append(s)
s.apply_async()
i += 1 #return chained_input
return chained_input

View File

@ -1,9 +1,19 @@
# standard imports # standard imports
import logging import logging
import os
# external imports
import pytest
from hexathon import (
strip_0x,
uniform as hex_uniform,
)
# local imports # local imports
from cic_eth.api.api_task import Api from cic_eth.api.api_task import Api
from cic_eth.task import BaseTask from cic_eth.task import BaseTask
from cic_eth.error import TrustError
from cic_eth.encode import tx_normalize
logg = logging.getLogger() logg = logging.getLogger()
@ -38,18 +48,25 @@ def test_tokens(
custodial_roles, custodial_roles,
foo_token_declaration, foo_token_declaration,
bar_token_declaration, bar_token_declaration,
celery_worker, celery_session_worker,
): ):
api = Api(str(default_chain_spec), queue=None) api = Api(str(default_chain_spec), queue=None)
t = api.token('FOO', proof=foo_token_declaration) t = api.token('FOO', proof=foo_token_declaration)
r = t.get_leaf() r = t.get()
logg.debug('r {}'.format(r))
assert len(r) == 1 assert len(r) == 1
assert r[0]['address'] == foo_token
t = api.tokens(['BAR', 'FOO'], proof=[[foo_token_declaration], [bar_token_declaration]]) t = api.tokens(['BAR', 'FOO'], proof=[[bar_token_declaration], [foo_token_declaration]])
r = t.get_leaf() r = t.get()
logg.debug('results {}'.format(r))
assert len(r) == 2 assert len(r) == 2
assert r[1]['address'] == foo_token assert r[1]['address'] == strip_0x(foo_token)
assert r[0]['address'] == bar_token assert r[0]['address'] == strip_0x(bar_token)
bogus_proof = os.urandom(32).hex()
with pytest.raises(TrustError):
t = api.token('FOO', proof=bogus_proof)
r = t.get_leaf()
logg.debug('should raise {}'.format(r))