Source code for microraiden.test.fixtures.accounts

import logging
from typing import List

import pytest

from eth_utils import (
    decode_hex,
    encode_hex,
    is_hex,
    remove_0x_prefix,
    keccak
)
import ethereum.tester
from web3 import Web3
from web3.contract import Contract

from microraiden.utils import (
    privkey_to_addr,
    create_signed_contract_transaction,
    create_signed_transaction,
    get_private_key
)
from microraiden.config import NETWORK_CFG
from microraiden.test.config import (
    RECEIVER_ETH_ALLOWANCE,
    RECEIVER_TOKEN_ALLOWANCE,
    SENDER_ETH_ALLOWANCE,
    SENDER_TOKEN_ALLOWANCE
)


log = logging.getLogger(__name__)


[docs]@pytest.fixture(scope='session') def private_key_seed(request) -> int: return request.config.getoption('private_key_seed')
[docs]@pytest.fixture(scope='session') def private_keys(private_key_seed: int) -> List[str]: """ Note: using 0 as the seed computes tester coinbase as the first address. This might cause issues, especially on sweeping all of these accounts, as the coinbase cannot be swept. """ return [encode_hex(keccak(str(private_key_seed + i))) for i in range(10)]
[docs]@pytest.fixture(scope='session') def faucet_password_path(request) -> str: return request.config.getoption('faucet_password_path')
[docs]@pytest.fixture(scope='session') def faucet_private_key(request, faucet_password_path: str) -> str: private_key = request.config.getoption('faucet_private_key') if is_hex(private_key): assert len(remove_0x_prefix(private_key)) == 64 return private_key else: private_key = get_private_key(private_key, faucet_password_path) assert private_key is not None, 'Error loading faucet private key from file.' return private_key
[docs]@pytest.fixture(scope='session') def faucet_address(faucet_private_key: str): return privkey_to_addr(faucet_private_key)
[docs]@pytest.fixture(scope='session') def make_account( request, web3: Web3, wait_for_transaction, use_tester: bool, token_contract: Contract, faucet_private_key: str, faucet_address: str ): def account_factory(eth_allowance: int, token_allowance: int, private_key: str): address = privkey_to_addr(private_key) if use_tester: ethereum.tester.accounts.append(decode_hex(address)) ethereum.tester.keys.append(decode_hex(private_key)) fund_account( address, eth_allowance, token_allowance, token_contract, web3, wait_for_transaction, faucet_private_key ) def finalize(): sweep_account(private_key, faucet_address, token_contract, web3, wait_for_transaction) if use_tester: ethereum.tester.accounts.remove(decode_hex(address)) ethereum.tester.keys.remove(decode_hex(private_key)) request.addfinalizer(finalize) return private_key return account_factory
[docs]def fund_account( address: str, eth_allowance: int, token_allowance: int, token_contract: Contract, web3: Web3, wait_for_transaction, faucet_private_key: str, ): log.info('Funding account {}'.format(address)) tx = create_signed_transaction( faucet_private_key, web3, to=address, value=eth_allowance ) tx_hash = web3.eth.sendRawTransaction(tx) wait_for_transaction(tx_hash) if token_allowance > 0: tx = create_signed_contract_transaction( faucet_private_key, token_contract, 'transfer', [ address, token_allowance ] ) tx_hash = web3.eth.sendRawTransaction(tx) wait_for_transaction(tx_hash)
[docs]def sweep_account( private_key: str, faucet_address: str, token_contract: Contract, web3: Web3, wait_for_transaction ): address = privkey_to_addr(private_key) log.info('Sweeping account {}'.format(address)) token_balance = token_contract.call().balanceOf(address) if token_balance > 0: tx = create_signed_contract_transaction( private_key, token_contract, 'transfer', [ faucet_address, token_balance ] ) try: tx_hash = web3.eth.sendRawTransaction(tx) except ValueError as e: if e.args[0]['message'].startswith('Insufficient funds.'): pass else: raise else: wait_for_transaction(tx_hash) assert token_contract.call().balanceOf(address) == 0 balance = web3.eth.getBalance(address) if balance < NETWORK_CFG.POT_GAS_LIMIT * NETWORK_CFG.GAS_PRICE: return tx = create_signed_transaction( private_key, web3, to=faucet_address, value=balance - NETWORK_CFG.POT_GAS_LIMIT * NETWORK_CFG.GAS_PRICE, gas_limit=NETWORK_CFG.POT_GAS_LIMIT ) tx_hash = web3.eth.sendRawTransaction(tx) wait_for_transaction(tx_hash) assert web3.eth.getBalance(address) == 0, ( 'Sweeping of account {} (private key {}) failed.'.format(address, private_key) )
[docs]@pytest.fixture(scope='session') def sender_privkey(make_account, private_keys: List[str]): return make_account(SENDER_ETH_ALLOWANCE, SENDER_TOKEN_ALLOWANCE, private_keys[0])
[docs]@pytest.fixture(scope='session') def sender_address(sender_privkey): return privkey_to_addr(sender_privkey)
[docs]@pytest.fixture(scope='session') def receiver_privkey(make_account, private_keys: List[str]): return make_account(RECEIVER_ETH_ALLOWANCE, RECEIVER_TOKEN_ALLOWANCE, private_keys[1])
[docs]@pytest.fixture(scope='session') def receiver_address(receiver_privkey): return privkey_to_addr(receiver_privkey)