Merge upstream contract migration
This commit is contained in:
@@ -3,9 +3,11 @@ import logging
|
||||
|
||||
# external imports
|
||||
import celery
|
||||
from erc20_single_shot_faucet import Faucet
|
||||
from erc20_single_shot_faucet import SingleShotFaucet as Faucet
|
||||
from chainlib.eth.constant import ZERO_ADDRESS
|
||||
from hexathon import strip_0x
|
||||
from hexathon import (
|
||||
strip_0x,
|
||||
)
|
||||
from chainlib.connection import RPCConnection
|
||||
from chainlib.eth.sign import (
|
||||
new_account,
|
||||
@@ -18,6 +20,7 @@ from chainlib.eth.tx import (
|
||||
)
|
||||
from chainlib.chain import ChainSpec
|
||||
from eth_accounts_index import AccountRegistry
|
||||
from sarafu_faucet import MinterFaucet as Faucet
|
||||
|
||||
# local import
|
||||
#from cic_eth.registry import safe_registry
|
||||
@@ -121,23 +124,18 @@ def register(self, account_address, chain_spec_dict, writer_address=None):
|
||||
|
||||
# Generate and sign transaction
|
||||
rpc_signer = RPCConnection.connect(chain_spec, 'signer')
|
||||
#nonce_oracle = self.create_nonce_oracle(writer_address, rpc)
|
||||
nonce_oracle = CustodialTaskNonceOracle(writer_address, self.request.root_id, session=session) #, default_nonce)
|
||||
gas_oracle = self.create_gas_oracle(rpc, AccountRegistry.gas)
|
||||
account_registry = AccountRegistry(signer=rpc_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle, chain_id=chain_spec.chain_id())
|
||||
(tx_hash_hex, tx_signed_raw_hex) = account_registry.add(account_registry_address, writer_address, account_address, tx_format=TxFormat.RLP_SIGNED)
|
||||
rpc_signer.disconnect()
|
||||
|
||||
# TODO: if cache task fails, task chain will not return
|
||||
cache_task = 'cic_eth.eth.account.cache_account_data'
|
||||
|
||||
# add transaction to queue
|
||||
cache_task = 'cic_eth.eth.account.cache_account_data'
|
||||
register_tx(tx_hash_hex, tx_signed_raw_hex, chain_spec, queue, cache_task=cache_task, session=session)
|
||||
session.commit()
|
||||
session.close()
|
||||
|
||||
#gas_budget = tx_add['gas'] * tx_add['gasPrice']
|
||||
|
||||
gas_pair = gas_oracle.get_gas(tx_signed_raw_hex)
|
||||
gas_budget = gas_pair[0] * gas_pair[1]
|
||||
logg.debug('register user tx {} {} {}'.format(tx_hash_hex, queue, gas_budget))
|
||||
@@ -156,7 +154,7 @@ def register(self, account_address, chain_spec_dict, writer_address=None):
|
||||
|
||||
|
||||
@celery_app.task(bind=True, base=CriticalSQLAlchemyAndSignerTask)
|
||||
def gift(self, account_address, chain_str):
|
||||
def gift(self, account_address, chain_spec_dict):
|
||||
"""Creates a transaction to invoke the faucet contract for the given address.
|
||||
|
||||
:param account_address: Ethereum address to give to
|
||||
@@ -166,28 +164,39 @@ def gift(self, account_address, chain_str):
|
||||
:returns: Raw signed transaction
|
||||
:rtype: list with transaction as only element
|
||||
"""
|
||||
chain_spec = ChainSpec.from_chain_str(chain_str)
|
||||
chain_spec = ChainSpec.from_dict(chain_spec_dict)
|
||||
|
||||
logg.debug('gift account address {} to index'.format(account_address))
|
||||
queue = self.request.delivery_info['routing_key']
|
||||
queue = self.request.delivery_info.get('routing_key')
|
||||
|
||||
c = RpcClient(chain_spec, holder_address=account_address)
|
||||
registry = safe_registry(c.w3)
|
||||
txf = AccountTxFactory(account_address, c, registry=registry)
|
||||
|
||||
#session = SessionBase.create_session()
|
||||
# Retrieve account index address
|
||||
session = self.create_session()
|
||||
tx_add = txf.gift(account_address, chain_spec, self.request.root_id, session=session)
|
||||
(tx_hash_hex, tx_signed_raw_hex) = sign_and_register_tx(tx_add, chain_str, queue, 'cic_eth.eth.account.cache_gift_data', session=session)
|
||||
rpc = RPCConnection.connect(chain_spec, 'default')
|
||||
registry = CICRegistry(chain_spec, rpc)
|
||||
faucet_address = registry.by_name('Faucet', sender_address=self.call_address)
|
||||
|
||||
# Generate and sign transaction
|
||||
rpc_signer = RPCConnection.connect(chain_spec, 'signer')
|
||||
nonce_oracle = CustodialTaskNonceOracle(account_address, self.request.root_id, session=session) #, default_nonce)
|
||||
gas_oracle = self.create_gas_oracle(rpc, Faucet.gas)
|
||||
faucet = Faucet(signer=rpc_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle, chain_id=chain_spec.chain_id())
|
||||
(tx_hash_hex, tx_signed_raw_hex) = faucet.give_to(faucet_address, account_address, account_address, tx_format=TxFormat.RLP_SIGNED)
|
||||
rpc_signer.disconnect()
|
||||
|
||||
# add transaction to queue
|
||||
cache_task = 'cic_eth.eth.account.cache_gift_data'
|
||||
register_tx(tx_hash_hex, tx_signed_raw_hex, chain_spec, queue, cache_task, session=session)
|
||||
session.commit()
|
||||
session.close()
|
||||
|
||||
gas_budget = tx_add['gas'] * tx_add['gasPrice']
|
||||
gas_pair = gas_oracle.get_gas(tx_signed_raw_hex)
|
||||
gas_budget = gas_pair[0] * gas_pair[1]
|
||||
logg.debug('register user tx {} {} {}'.format(tx_hash_hex, queue, gas_budget))
|
||||
rpc.disconnect()
|
||||
|
||||
logg.debug('gift user tx {}'.format(tx_hash_hex))
|
||||
s = create_check_gas_and_send_task(
|
||||
s = create_check_gas_task(
|
||||
[tx_signed_raw_hex],
|
||||
chain_str,
|
||||
chain_spec,
|
||||
account_address,
|
||||
gas_budget,
|
||||
[tx_hash_hex],
|
||||
@@ -199,7 +208,7 @@ def gift(self, account_address, chain_str):
|
||||
|
||||
|
||||
@celery_app.task(bind=True)
|
||||
def have(self, account, chain_str):
|
||||
def have(self, account, chain_spec_dict):
|
||||
"""Check whether the given account exists in keystore
|
||||
|
||||
:param account: Account to check
|
||||
@@ -209,7 +218,7 @@ def have(self, account, chain_str):
|
||||
:returns: Account, or None if not exists
|
||||
:rtype: Varies
|
||||
"""
|
||||
chain_spec = ChainSpec.from_chain_str(chain_str)
|
||||
chain_spec = ChainSpec.from_dict(chain_spec_dict)
|
||||
o = sign_message(account, '0x2a')
|
||||
try:
|
||||
conn = RPCConnection.connect(chain_spec, 'signer')
|
||||
@@ -249,7 +258,7 @@ def cache_gift_data(
|
||||
self,
|
||||
tx_hash_hex,
|
||||
tx_signed_raw_hex,
|
||||
chain_spec,
|
||||
chain_spec_dict,
|
||||
):
|
||||
"""Generates and commits transaction cache metadata for a Faucet.giveTo transaction
|
||||
|
||||
@@ -262,14 +271,12 @@ def cache_gift_data(
|
||||
:returns: Transaction hash and id of cache element in storage backend, respectively
|
||||
:rtype: tuple
|
||||
"""
|
||||
chain_spec = ChainSpec.from_chain_str(chain_str)
|
||||
c = RpcClient(chain_spec)
|
||||
chain_spec = ChainSpec.from_dict(chain_spec_dict)
|
||||
|
||||
tx_signed_raw_bytes = bytes.fromhex(tx_signed_raw_hex[2:])
|
||||
tx_signed_raw_bytes = bytes.fromhex(strip_0x(tx_signed_raw_hex))
|
||||
tx = unpack(tx_signed_raw_bytes, chain_spec.chain_id())
|
||||
tx_data = unpack_gift(tx['data'])
|
||||
tx_data = Faucet.parse_give_to_request(tx['data'])
|
||||
|
||||
#session = SessionBase.create_session()
|
||||
session = self.create_session()
|
||||
|
||||
tx_cache = TxCache(
|
||||
@@ -311,8 +318,7 @@ def cache_account_data(
|
||||
chain_spec = ChainSpec.from_dict(chain_spec_dict)
|
||||
tx_signed_raw_bytes = bytes.fromhex(tx_signed_raw_hex[2:])
|
||||
tx = unpack(tx_signed_raw_bytes, chain_id=chain_spec.chain_id())
|
||||
raise NotImplementedError('unpack register must be replaced with AccountRegistry parser')
|
||||
tx_data = unpack_register(tx['data'])
|
||||
tx_data = AccountRegistry.parse_add_request(tx['data'])
|
||||
|
||||
session = SessionBase.create_session()
|
||||
tx_cache = TxCache(
|
||||
|
||||
@@ -7,41 +7,29 @@ from hexathon import (
|
||||
strip_0x,
|
||||
add_0x,
|
||||
)
|
||||
from chainlib.eth.address import to_checksum
|
||||
from chainlib.eth.address import to_checksum_address
|
||||
from chainlib.eth.constant import ZERO_ADDRESS
|
||||
from chainlib.eth.contract import (
|
||||
ABIContractType,
|
||||
abi_decode_single,
|
||||
)
|
||||
from cic_eth_registry import CICRegistry
|
||||
from erc20_transfer_authorization import TransferAuthorization
|
||||
|
||||
# local imports
|
||||
from .base import SyncFilter
|
||||
|
||||
|
||||
logg = logging.getLogger(__name__)
|
||||
|
||||
transfer_request_signature = 'ed71262a'
|
||||
|
||||
def unpack_create_request(data):
|
||||
|
||||
data = strip_0x(data)
|
||||
cursor = 0
|
||||
f = data[cursor:cursor+8]
|
||||
cursor += 8
|
||||
|
||||
if f != transfer_request_signature:
|
||||
raise ValueError('Invalid create request data ({})'.format(f))
|
||||
|
||||
o = {}
|
||||
o['sender'] = data[cursor+24:cursor+64]
|
||||
cursor += 64
|
||||
o['recipient'] = data[cursor+24:cursor+64]
|
||||
cursor += 64
|
||||
o['token'] = data[cursor+24:cursor+64]
|
||||
cursor += 64
|
||||
o['value'] = int(data[cursor:], 16)
|
||||
return o
|
||||
|
||||
|
||||
class TransferAuthFilter(SyncFilter):
|
||||
|
||||
def __init__(self, registry, chain_spec, queue=None):
|
||||
def __init__(self, registry, chain_spec, conn, queue=None, call_address=ZERO_ADDRESS):
|
||||
self.queue = queue
|
||||
self.chain_spec = chain_spec
|
||||
self.transfer_request_contract = registry.get_contract(self.chain_spec, 'TransferAuthorization')
|
||||
registry = CICRegistry(chain_spec, conn)
|
||||
self.transfer_request_contract = registry.by_name('TransferAuthorization', sender_address=call_address)
|
||||
|
||||
|
||||
def filter(self, conn, block, tx, session): #rcpt, chain_str, session=None):
|
||||
@@ -61,11 +49,13 @@ class TransferAuthFilter(SyncFilter):
|
||||
logg.debug('not our transfer auth contract address {}'.format(recipient))
|
||||
return False
|
||||
|
||||
o = unpack_create_request(tx.payload)
|
||||
r = TransferAuthorization.parse_create_request_request(tx.payload)
|
||||
|
||||
sender = add_0x(to_checksum(o['sender']))
|
||||
recipient = add_0x(to_checksum(recipient))
|
||||
token = add_0x(to_checksum(o['token']))
|
||||
sender = abi_decode_single(ABIContractType.ADDRESS, r[0])
|
||||
recipient = abi_decode_single(ABIContractType.ADDRESS, r[1])
|
||||
token = abi_decode_single(ABIContractType.ADDRESS, r[2])
|
||||
value = abi_decode_single(ABIContractType.UINT256, r[3])
|
||||
|
||||
token_data = {
|
||||
'address': token,
|
||||
}
|
||||
@@ -83,8 +73,8 @@ class TransferAuthFilter(SyncFilter):
|
||||
[
|
||||
sender,
|
||||
recipient,
|
||||
o['value'],
|
||||
str(self.chain_spec),
|
||||
value,
|
||||
self.chain_spec.asdict(),
|
||||
],
|
||||
queue=self.queue,
|
||||
)
|
||||
|
||||
@@ -7,6 +7,8 @@ import time
|
||||
import pytest
|
||||
import celery
|
||||
from chainlib.connection import RPCConnection
|
||||
from chainlib.eth.nonce import RPCNonceOracle
|
||||
from chainlib.eth.tx import receipt
|
||||
from eth_accounts_index import AccountRegistry
|
||||
from hexathon import strip_0x
|
||||
|
||||
@@ -22,7 +24,6 @@ from cic_eth.db.models.role import AccountRole
|
||||
logg = logging.getLogger()
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_create_account(
|
||||
default_chain_spec,
|
||||
eth_rpc,
|
||||
@@ -121,7 +122,6 @@ def test_register_account(
|
||||
assert int(strip_0x(r), 16) == 1
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_role_task(
|
||||
default_chain_spec,
|
||||
init_database,
|
||||
@@ -136,9 +136,53 @@ def test_role_task(
|
||||
'cic_eth.eth.account.role',
|
||||
[
|
||||
address,
|
||||
str(default_chain_spec),
|
||||
default_chain_spec.asdict(),
|
||||
],
|
||||
)
|
||||
t = s.apply_async()
|
||||
r = t.get()
|
||||
assert r == 'foo'
|
||||
|
||||
|
||||
|
||||
def test_gift(
|
||||
init_database,
|
||||
default_chain_spec,
|
||||
contract_roles,
|
||||
agent_roles,
|
||||
account_registry,
|
||||
faucet,
|
||||
eth_rpc,
|
||||
eth_signer,
|
||||
init_celery_tasks,
|
||||
cic_registry,
|
||||
celery_session_worker,
|
||||
):
|
||||
|
||||
nonce_oracle = RPCNonceOracle(contract_roles['ACCOUNT_REGISTRY_WRITER'], eth_rpc)
|
||||
c = AccountRegistry(signer=eth_signer, nonce_oracle=nonce_oracle, chain_id=default_chain_spec.chain_id())
|
||||
(tx_hash_hex, o) = c.add(account_registry, contract_roles['ACCOUNT_REGISTRY_WRITER'], agent_roles['ALICE'])
|
||||
eth_rpc.do(o)
|
||||
o = receipt(tx_hash_hex)
|
||||
r = eth_rpc.do(o)
|
||||
assert r['status'] == 1
|
||||
|
||||
s_nonce = celery.signature(
|
||||
'cic_eth.eth.tx.reserve_nonce',
|
||||
[
|
||||
agent_roles['ALICE'],
|
||||
],
|
||||
queue=None,
|
||||
)
|
||||
|
||||
s_gift = celery.signature(
|
||||
'cic_eth.eth.account.gift',
|
||||
[
|
||||
default_chain_spec.asdict(),
|
||||
],
|
||||
queue=None,
|
||||
)
|
||||
s_nonce.link(s_gift)
|
||||
t = s_nonce.apply_async()
|
||||
r = t.get_leaf()
|
||||
assert t.successful()
|
||||
|
||||
Reference in New Issue
Block a user