def test_deprecation_executor(
    web3,
    contracts_manager,
    deploy_contract,
    secret_registry_contract,
    custom_token,
    get_accounts,
):
    (deprecation_executor, B) = get_accounts(2)

    json_contract = contracts_manager.get_contract(
        CONTRACT_TOKEN_NETWORK_REGISTRY)
    token_network_registry = deploy_contract(
        web3,
        deprecation_executor,
        json_contract['abi'],
        json_contract['bin'],
        [
            secret_registry_contract.address,
            int(web3.version.network),
            TEST_SETTLE_TIMEOUT_MIN,
            TEST_SETTLE_TIMEOUT_MAX,
        ],
    )

    # Make sure deployer is deprecation_executor
    assert token_network_registry.functions.deprecation_executor().call(
    ) == deprecation_executor
    assert token_network_registry.functions.token_network_created().call(
    ) is False

    # We can only deploy one TokenNetwork contract
    # It can be deployed by anyone
    tx_hash = token_network_registry.functions.createERC20TokenNetwork(
        custom_token.address, ).transact({'from': B}, )
    assert token_network_registry.functions.token_network_created().call(
    ) is True

    # No other TokenNetworks can be deployed now
    with pytest.raises(TransactionFailed):
        token_network_registry.functions.createERC20TokenNetwork(
            custom_token.address, ).transact({'from': B}, )
    with pytest.raises(TransactionFailed):
        token_network_registry.functions.createERC20TokenNetwork(
            custom_token.address, ).transact({'from': deprecation_executor}, )

    tx_receipt = web3.eth.getTransactionReceipt(tx_hash)
    event_abi = contracts_manager.get_event_abi(
        CONTRACT_TOKEN_NETWORK_REGISTRY,
        EVENT_TOKEN_NETWORK_CREATED,
    )
    event_data = get_event_data(event_abi, tx_receipt['logs'][0])
    token_network_address = event_data['args']['token_network_address']
    token_network = web3.eth.contract(
        abi=contracts_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK),
        address=token_network_address,
    )

    assert token_network.functions.deprecation_executor().call(
    ) == deprecation_executor
Ejemplo n.º 2
0
def test_deprecation_immediate_payout(create_account: Callable,
                                      custom_token: Contract,
                                      service_registry: Contract,
                                      web3: Web3) -> None:
    """When the deprecation switch is on, deposits can be withdrawn immediately."""
    # A user makes a deposit
    A = create_account()
    minted = service_registry.functions.currentPrice().call()
    call_and_transact(custom_token.functions.mint(minted), {"from": A})
    call_and_transact(
        custom_token.functions.approve(service_registry.address, minted),
        {"from": A})
    deposit_tx = call_and_transact(service_registry.functions.deposit(minted),
                                   {"from": A})
    # The user obtains the deposit address
    deposit_tx_receipt = web3.eth.get_transaction_receipt(deposit_tx)
    contract_manager = ContractManager(
        contracts_precompiled_path(version=None))
    event_abi = contract_manager.get_event_abi(CONTRACT_SERVICE_REGISTRY,
                                               EVENT_REGISTERED_SERVICE)
    event_data = get_event_data(web3.codec, event_abi,
                                deposit_tx_receipt["logs"][-1])
    deposit_address = event_data["args"]["deposit_contract"]
    # And obtains the Deposit contract instance
    deposit_abi = contract_manager.get_contract_abi(CONTRACT_DEPOSIT)
    deposit = web3.eth.contract(abi=deposit_abi, address=deposit_address)
    # The controller turns on the deprecation switch
    call_and_transact(service_registry.functions.setDeprecationSwitch(),
                      {"from": DEPLOYER_ADDRESS})
    # The user successfully withdraws the deposit
    call_and_transact(deposit.functions.withdraw(A), {"from": A})
    # The user has all the balance it has minted
    assert minted == custom_token.functions.balanceOf(A).call()
    # The Deposit contract has destroyed itself
    assert web3.eth.get_code(deposit.address) == HexBytes("0x")
Ejemplo n.º 3
0
def test_setURL(custom_token: Contract, service_registry: Contract,
                get_accounts: Callable, web3: Web3) -> None:
    """A ServiceRegistry allows registered service providers to set their URLs"""
    (A, ) = get_accounts(1)
    url1 = "http://example.com"
    url2 = "http://raiden.example.com"

    call_and_transact(custom_token.functions.mint(SERVICE_DEPOSIT),
                      {"from": A})
    call_and_transact(
        custom_token.functions.approve(service_registry.address,
                                       SERVICE_DEPOSIT),
        {"from": A},
    )
    tx = call_and_transact(service_registry.functions.deposit(SERVICE_DEPOSIT),
                           {"from": A})
    tx_receipt = web3.eth.get_transaction_receipt(tx)
    contract_manager = ContractManager(
        contracts_precompiled_path(version=None))
    event_abi = contract_manager.get_event_abi(CONTRACT_SERVICE_REGISTRY,
                                               EVENT_REGISTERED_SERVICE)
    event_data = get_event_data(web3.codec, event_abi, tx_receipt["logs"][-1])
    assert event_data["args"]["service"] == A
    assert event_data["args"]["deposit_contract"] != EMPTY_ADDRESS

    call_and_transact(service_registry.functions.setURL(url1), {"from": A})
    assert service_registry.functions.urls(A).call() == url1

    call_and_transact(service_registry.functions.setURL(url2), {"from": A})
    assert service_registry.functions.urls(A).call() == url2
def test_set_deprecation_switch(get_accounts: Callable,
                                token_network: Contract, web3: Web3,
                                contracts_manager: ContractManager) -> None:
    """ The deprecation executor deprecates a TokenNetwork contract """
    (A) = get_accounts(1)[0]
    deprecation_executor = token_network.functions.deprecation_executor().call(
    )

    assert token_network.functions.safety_deprecation_switch().call() is False

    with pytest.raises(TransactionFailed):
        token_network.functions.deprecate().call({"from": A})

    tx = token_network.functions.deprecate().call_and_transact(
        {"from": deprecation_executor})
    assert token_network.functions.safety_deprecation_switch().call() is True
    tx_receipt = web3.eth.getTransactionReceipt(tx)
    event_abi = contracts_manager.get_event_abi(CONTRACT_TOKEN_NETWORK,
                                                EVENT_DEPRECATION_SWITCH)
    event_data = get_event_data(event_abi, tx_receipt["logs"][0])
    assert event_data["args"]["new_value"]

    # We should not be able to call it again
    with pytest.raises(TransactionFailed):
        token_network.functions.deprecate().call({"from": A})
Ejemplo n.º 5
0
async def process_storage_history(start_height=0):
    web3 = get_web3()
    contract = get_storage_contract(web3)
    abi = contract.events.NewHash._get_event_abi()
    topic = construct_event_topic_set(abi, web3.codec)

    start = max(start_height, settings.ethereum_min_height)
    last_height = start
    end_height = web3.eth.blockNumber
    count = 0

    async for i in get_logs(web3, contract, start, topics=topic):
        count += 1
        evt_data = get_event_data(web3.codec, abi, i)
        args = evt_data['args']
        height = evt_data['blockNumber']
        LOGGER.debug(f"{height}: {evt_data}")
        context = {
            "source_chain": 'ETH',
            "source_contract": settings.ethereum_event_contract,
            "tx_hash": evt_data.transactionHash.hex(),
            "height": evt_data.blockNumber,
            "submitter": args['hashSubmitter']
        }
        yield (context, args["hash"])

    LOGGER.info(f"Scanned {count} events")
Ejemplo n.º 6
0
 def get(
     token_network_registry: Contract,
     token_address: HexAddress,
     channel_participant_deposit_limit: int,
     token_network_deposit_limit: int,
 ) -> Contract:
     tx_hash = call_and_transact(
         token_network_registry.functions.createERC20TokenNetwork(
             token_address,
             channel_participant_deposit_limit,
             token_network_deposit_limit,
         ),
         {"from": DEPLOYER_ADDRESS},
     )
     tx_receipt = web3.eth.getTransactionReceipt(tx_hash)
     event_abi = contracts_manager.get_event_abi(
         CONTRACT_TOKEN_NETWORK_REGISTRY, EVENT_TOKEN_NETWORK_CREATED)
     event_data = get_event_data(abi_codec=web3.codec,
                                 event_abi=event_abi,
                                 log_entry=tx_receipt["logs"][0])
     contract_address = event_data["args"]["token_network_address"]
     contract = web3.eth.contract(
         abi=contracts_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK),
         address=contract_address,
     )
     return contract
Ejemplo n.º 7
0
def decode_event(abi_codec: ABICodec, log_entry: LogReceipt) -> Dict:
    topic = log_entry["topics"][0]
    event_abi = EVENT_TOPIC_TO_ABI[topic]

    return get_event_data(abi_codec=abi_codec,
                          event_abi=event_abi,
                          log_entry=log_entry)
 def f(initial_amount: int, decimals: int, token_name: str,
       token_symbol: str) -> Contract:
     token_contract = deploy_token_contract(initial_amount, decimals,
                                            token_name, token_symbol)
     txid = call_and_transact(
         token_network_registry_contract.functions.createERC20TokenNetwork(
             token_contract.address,
             channel_participant_deposit_limit,
             token_network_deposit_limit,
         ),
         {"from": DEPLOYER_ADDRESS},
     )
     (tx_receipt, _) = check_successful_tx(web3, txid)
     assert len(tx_receipt["logs"]) == 1
     event_abi = contracts_manager.get_event_abi(
         CONTRACT_TOKEN_NETWORK_REGISTRY, EVENT_TOKEN_NETWORK_CREATED)
     decoded_event = get_event_data(event_abi, tx_receipt["logs"][0])
     assert decoded_event is not None
     assert is_address(decoded_event["args"]["token_address"])
     assert is_address(decoded_event["args"]["token_network_address"])
     token_network_address = decoded_event["args"]["token_network_address"]
     token_network_abi = contracts_manager.get_contract_abi(
         CONTRACT_TOKEN_NETWORK)
     return web3.eth.contract(abi=token_network_abi,
                              address=token_network_address)
Ejemplo n.º 9
0
def process_pool_history(pool, per_block, start_height, end_height):
    abi = pool['contract'].events.Transfer._get_event_abi()
    web3 = get_web3()
    topic = construct_event_topic_set(abi, web3.codec)
    weights = dict()
    balances = dict()
    reward_start = max(pool['start_height'], config['reward_start'],
                       start_height)
    last_height = reward_start
    end_height = min(web3.eth.blockNumber, end_height)

    def update_weights(since, current):
        for addr, value in balances.items():
            if value > 0:
                weights[addr] = weights.get(addr, 0) + (value *
                                                        (current - since))

    for i in get_logs(web3,
                      pool['contract'],
                      pool['start_height'],
                      topics=topic):
        evt_data = get_event_data(web3.codec, abi, i)
        args = evt_data['args']
        height = evt_data['blockNumber']
        if height > end_height:
            break

        if height > reward_start:
            update_weights(last_height, height)

        # to handle gaps in our staking contract's reward distribution,
        # a user's balance accumulates whenever they stake to the contract
        if args['src'] == '0xFe82ea0Ef14DfdAcd5dB1D49F563497A1a751bA1':
            balances[args.dst] = balances.get(args.dst, 0) - args.amt
        elif args.dst == '0xFe82ea0Ef14DfdAcd5dB1D49F563497A1a751bA1':
            balances[args['src']] = balances.get(args['src'], 0) + args.amt
        last_height = height

    height = end_height
    update_weights(last_height, height)
    total_weight = sum(weights.values())
    total_balance = sum([b for b in balances.values() if b > 0])
    weights = {a: w / total_weight for a, w in weights.items() if w > 0}
    print(weights)
    balparts = {a: w / total_balance for a, w in balances.items() if w > 0}
    print(balparts)

    total_blocks = height - reward_start
    reward_owed = {a: w * per_block * total_blocks for a, w in weights.items()}
    print(reward_owed)
    print("Total", sum(reward_owed.values()))
    return reward_owed, start_height, end_height
Ejemplo n.º 10
0
async def process_contract_history(contract_address,
                                   start_height,
                                   platform="ETH",
                                   balances=None,
                                   last_seen=None):
    web3 = get_web3()
    contract = get_contract(contract_address, web3)
    abi = contract.events.Transfer._get_event_abi()
    topic = construct_event_topic_set(abi, web3.codec)
    if balances is None:
        balances = {
            settings.ethereum_deployer:
            settings.ethereum_total_supply * DECIMALS
        }
    last_height = start_height
    end_height = web3.eth.blockNumber

    changed_addresses = set()

    to_append = list()

    async for i in get_logs(web3, contract, start_height, topics=topic):
        evt_data = get_event_data(web3.codec, abi, i)
        args = evt_data['args']
        height = evt_data['blockNumber']

        if height != last_height:
            yield (last_height, (balances, platform, changed_addresses))
            changed_addresses = set()

            if last_seen is not None:
                last_seen.extend(to_append)

            to_append = list()

        if last_seen is not None:
            tx_hash = evt_data.transactionHash.hex()
            if tx_hash in last_seen:
                continue
            else:
                to_append.append(tx_hash)

        balances[args['_from']] = (balances.get(args['_from'], 0) -
                                   args['_value'])
        balances[args['_to']] = balances.get(args['_to'], 0) + args['_value']
        changed_addresses.add(args['_from'])
        changed_addresses.add(args['_to'])
        last_height = height

    if len(changed_addresses):
        yield (last_height, (balances, platform, changed_addresses))
Ejemplo n.º 11
0
def process_pool_history(pool, per_block, start_height, end_height):
    abi = pool['contract'].events.Transfer._get_event_abi()
    web3 = get_web3()
    topic = construct_event_topic_set(abi, web3.codec)
    weights = dict()
    balances = dict()
    reward_start = max(pool['start_height'], config['reward_start'], start_height)
    last_height = reward_start
    end_height = min(web3.eth.blockNumber, end_height)

    def update_weights(since, current):
        for addr, value in balances.items():
            # skip LBP deployer address
            if addr == '0xC98A0A4d9D9F789b86f03AbfdcEaEE7e3538e3dF':
                continue
            if value > 0:
                weights[addr] = weights.get(addr, 0) + (value * (current-since))

    for i in get_logs(web3, pool['contract'], pool['start_height'], topics=topic):
        evt_data = get_event_data(web3.codec, abi, i)
        args = evt_data['args']
        height = evt_data['blockNumber']
        if height > end_height:
            break

        if height > reward_start:
            update_weights(last_height, height)

        # to handle gaps in our staking contract's reward distribution,
        # a user's balance accumulates whenever they stake to the contract
        if args['from'] == '0x0310DEE97b42063BbB46d02a674727C13eb79cFD':
            balances[args.to] = balances.get(args.to, 0) - args.value
        elif args.to == '0x0310DEE97b42063BbB46d02a674727C13eb79cFD':
            balances[args['from']] = balances.get(args['from'], 0) + args.value
        last_height = height
    
    height = end_height
    update_weights(last_height, height)
    total_weight = sum(weights.values())
    total_balance = sum([b for b in balances.values() if b > 0])
    weights = {a: w / total_weight for a, w in weights.items() if w > 0}
    print(weights)
    balparts = {a: w / total_balance for a, w in balances.items() if w > 0}
    print(balparts)

    total_blocks = height - reward_start
    reward_owed = {a: w*per_block*total_blocks for a, w in weights.items()}
    print(reward_owed)
    print("Total", sum(reward_owed.values()))
    return reward_owed, start_height, end_height
Ejemplo n.º 12
0
async def request_transactions(config, web3, contract, start_height):
    """ Continuously request data from the Ethereum blockchain.
    TODO: support websocket API.
    """

    last_height = 0
    seen_ids = []

    logs = get_logs(config, web3, contract, start_height + 1)

    async for log in logs:
        event_data = get_event_data(contract.events.SyncEvent._get_event_abi(),
                                    log)
        LOGGER.info('Handling TX in block %s' % event_data.blockNumber)
        publisher = event_data.args.addr  # TODO: verify rights.

        last_height = event_data.blockNumber

        message = event_data.args.message
        try:
            jdata = json.loads(message)

            messages = await get_chaindata_messages(
                jdata,
                seen_ids=seen_ids,
                context={
                    "tx_hash": event_data.transactionHash,
                    "height": event_data.blockNumber,
                    "publisher": publisher
                })

            if messages is not None:
                yield dict(type="aleph",
                           tx_hash=event_data.transactionHash,
                           height=event_data.blockNumber,
                           publisher=publisher,
                           messages=messages)

        except json.JSONDecodeError:
            # if it's not valid json, just ignore it...
            LOGGER.info("Incoming logic data is not JSON, ignoring. %r" %
                        message)

        except Exception:
            LOGGER.exception("Can't decode incoming logic data %r" % message)

        # Since we got no critical exception, save last received object
        # block height to do next requests from there.
        if last_height:
            await Chain.set_last_height(CHAIN_NAME, last_height)
Ejemplo n.º 13
0
 def get(token_address):
     tx_hash = token_network_registry_contract.functions.createERC20TokenNetwork(
         token_address, ).transact({'from': owner})
     tx_receipt = web3.eth.getTransactionReceipt(tx_hash)
     event_abi = contracts_manager.get_event_abi(
         CONTRACT_TOKEN_NETWORK_REGISTRY,
         EVENT_TOKEN_NETWORK_CREATED,
     )
     event_data = get_event_data(event_abi, tx_receipt['logs'][0])
     contract_address = event_data['args']['token_network_address']
     contract = web3.eth.contract(
         abi=contracts_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK),
         address=contract_address,
     )
     return contract
Ejemplo n.º 14
0
def process_pool_history(pool, per_block, start_height, end_height):
    abi = pool['contract'].events.Transfer._get_event_abi()
    web3 = get_web3()
    topic = construct_event_topic_set(abi, web3.codec)
    weights = dict()
    balances = dict()
    reward_start = max(pool['start_height'], config['reward_start'],
                       start_height)
    last_height = reward_start
    end_height = min(web3.eth.blockNumber, end_height)

    def update_weights(since, current):
        for addr, value in balances.items():
            if value > 0:
                weights[addr] = weights.get(addr, 0) + (value *
                                                        (current - since))

    for i in get_logs(web3,
                      pool['contract'],
                      pool['start_height'],
                      topics=topic):
        evt_data = get_event_data(web3.codec, abi, i)
        args = evt_data['args']
        height = evt_data['blockNumber']
        if height > end_height:
            break

        if height > reward_start:
            update_weights(last_height, height)

        balances[args['from']] = balances.get(args['from'], 0) - args.value
        balances[args.to] = balances.get(args.to, 0) + args.value
        last_height = height

    height = end_height
    update_weights(last_height, height)
    total_weight = sum(weights.values())
    total_balance = sum([b for b in balances.values() if b > 0])
    weights = {a: w / total_weight for a, w in weights.items() if w > 0}
    print(weights)
    balparts = {a: w / total_balance for a, w in balances.items() if w > 0}
    print(balparts)

    total_blocks = height - reward_start
    reward_owed = {a: w * per_block * total_blocks for a, w in weights.items()}
    print(reward_owed)
    print("Total", sum(reward_owed.values()))
    return reward_owed, start_height, end_height
Ejemplo n.º 15
0
 def get(token_address):
     tx_hash = token_network_registry.transact({'from': owner}).createERC20TokenNetwork(
         token_address
     )
     tx_receipt = web3.eth.getTransactionReceipt(tx_hash)
     event_abi = contracts_manager.get_event_abi(
         C_TOKEN_NETWORK_REGISTRY,
         'TokenNetworkCreated'
     )
     event_data = get_event_data(event_abi, tx_receipt['logs'][0])
     contract_address = event_data['args']['token_network_address']
     contract = web3.eth.contract(
         abi=contracts_manager.get_contract_abi(C_TOKEN_NETWORK),
         address=contract_address
     )
     return contract
Ejemplo n.º 16
0
 def f(initial_amount: int, decimals: int, token_name: str, token_symbol: str):
     token_contract = deploy_token_contract(initial_amount, decimals, token_name, token_symbol)
     txid = token_network_registry_contract.functions.createERC20TokenNetwork(
         token_contract.address,
     ).transact({'from': contract_deployer_address})
     tx_receipt = wait_for_transaction(txid)
     assert len(tx_receipt['logs']) == 1
     event_abi = contracts_manager.get_event_abi(
         CONTRACT_TOKEN_NETWORK_REGISTRY,
         EVENT_TOKEN_NETWORK_CREATED,
     )
     decoded_event = get_event_data(event_abi, tx_receipt['logs'][0])
     assert decoded_event is not None
     assert is_address(decoded_event['args']['token_address'])
     assert is_address(decoded_event['args']['token_network_address'])
     token_network_address = decoded_event['args']['token_network_address']
     token_network_abi = contracts_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK)
     return web3.eth.contract(abi=token_network_abi, address=token_network_address)
Ejemplo n.º 17
0
def decode_event(abi: ABI, log_: Dict) -> Dict:
    """ Helper function to unpack event data using a provided ABI

    Args:
        abi: The ABI of the contract, not the ABI of the event
        log_: The raw event data

    Returns:
        The decoded event
    """
    if isinstance(log_["topics"][0], str):
        log_["topics"][0] = decode_hex(log_["topics"][0])
    elif isinstance(log_["topics"][0], int):
        log_["topics"][0] = decode_hex(hex(log_["topics"][0]))
    event_id = log_["topics"][0]
    events = filter_by_type("event", abi)
    topic_to_event_abi = {event_abi_to_log_topic(event_abi): event_abi for event_abi in events}
    event_abi = topic_to_event_abi[event_id]
    return get_event_data(event_abi, log_)
 def get(
     token_address,
     channel_participant_deposit_limit: int,
     token_network_deposit_limit: int,
 ):
     tx_hash = token_network_registry_contract.functions.createERC20TokenNetwork(
         token_address,
         channel_participant_deposit_limit,
         token_network_deposit_limit,
     ).transact({'from': CONTRACT_DEPLOYER_ADDRESS})
     tx_receipt = web3.eth.getTransactionReceipt(tx_hash)
     event_abi = contracts_manager.get_event_abi(
         CONTRACT_TOKEN_NETWORK_REGISTRY,
         EVENT_TOKEN_NETWORK_CREATED,
     )
     event_data = get_event_data(event_abi, tx_receipt['logs'][0])
     contract_address = event_data['args']['token_network_address']
     contract = web3.eth.contract(
         abi=contracts_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK),
         address=contract_address,
     )
     return contract
Ejemplo n.º 19
0
def token_network_addresses_from_registry(
    web3: Web3,
    contract_manager: ContractManager,
    token_network_registry: Contract,
    token_addresses: List[Address],
) -> List[Address]:

    token_network_addresses = []

    for token_address in token_addresses:
        tx = token_network_registry.functions.createERC20TokenNetwork(
            token_address).transact()
        receipt = web3.eth.getTransactionReceipt(tx)

        event_data = get_event_data(
            contract_manager.get_event_abi('TokenNetworkRegistry',
                                           'TokenNetworkCreated'),
            receipt['logs'][0])
        token_network_address = event_data['args']['token_network_address']

        token_network_addresses.append(token_network_address)

    return token_network_addresses
Ejemplo n.º 20
0
def process_contract_history(contract_address, start_height, end_height):
    web3 = get_web3()
    contract = get_contract(contract_address, web3)
    abi = contract.events.Transfer._get_event_abi()
    topic = construct_event_topic_set(abi, web3.codec)
    weights = dict()
    balances = dict()
    last_height = start_height
    end_height = min(web3.eth.blockNumber, end_height)

    for i in get_logs(web3, contract, start_height, topics=topic):
        evt_data = get_event_data(web3.codec, abi, i)
        args = evt_data['args']
        height = evt_data['blockNumber']
        if height > end_height:
            break

        balances[args['_from']] = balances.get(args['_from'],
                                               0) - args['_value']
        balances[args['_to']] = balances.get(args['_to'], 0) + args['_value']
        last_height = height

    height = end_height
    return balances
Ejemplo n.º 21
0
async def process_contract_history(contract_address,
                                   start_height,
                                   balances=None,
                                   streams=None,
                                   last_seen=None):
    web3 = get_web3()
    contract = get_contract(contract_address, web3)

    contract_events = get_contract_params(
        web3, contract, ["CreateStream", "WithdrawFromStream", "CancelStream"])

    # abi = contract.events.Transfer._get_event_abi()
    # topic = construct_event_topic_set(abi, web3.codec)
    if balances is None:
        balances = {}
    if streams is None:
        streams = {}

    last_height = start_height
    end_height = web3.eth.blockNumber

    changed_addresses = set()

    to_append = list()

    async for i in get_logs(web3, contract, start_height):
        message_topics = [t.hex() for t in i['topics']]
        evt_data = None
        for topic, (abi, topic_hash) in contract_events.items():
            if topic_hash in message_topics:
                print("found", topic)
                evt_data = get_event_data(web3.codec, abi, i)

        if evt_data is None:
            continue

        # yield evt_data
        args = evt_data['args']
        height = evt_data['blockNumber']

        if height != last_height:
            yield (last_height, (balances, streams, changed_addresses))
            changed_addresses = set()

            if last_seen is not None:
                last_seen.extend(to_append)

            to_append = list()

        if last_seen is not None:
            tx_hash = evt_data.transactionHash.hex()
            if tx_hash in last_seen:
                continue
            else:
                to_append.append(tx_hash)

        if (evt_data["event"] == "CreateStream"
                and args["tokenAddress"] == settings.ethereum_token_contract):
            balances[args["recipient"]] = balances.get(args["recipient"], 0) \
                                          + args["deposit"]
            changed_addresses.add(args['recipient'])
            streams[args["streamId"]] = {"balance": args["deposit"], **args}

        elif (evt_data["event"] == "CancelStream"
              and args["streamId"] in streams):
            balances[args["recipient"]] -= streams[args["streamId"]]["balance"]
            changed_addresses.add(args['recipient'])
            del streams[args["streamId"]]

        elif (evt_data["event"] == "WithdrawFromStream"
              and args["streamId"] in streams):
            balances[args["recipient"]] -= args['amount']
            streams[args["streamId"]]["balance"] -= args['amount']
            if streams[args["streamId"]]["balance"] == 0:
                del streams[args["streamId"]]

            changed_addresses.add(args['recipient'])

        # balances[args['_from']] = (balances.get(args['_from'], 0)
        #                            - args['_value'])
        # balances[args['_to']] = balances.get(args['_to'], 0) + args['_value']
        # changed_addresses.add(args['_from'])
        # changed_addresses.add(args['_to'])
        last_height = height

    if len(changed_addresses):
        yield (last_height, (balances, streams, changed_addresses))
Ejemplo n.º 22
0
def decode_event(topic_to_event_abi: Dict[bytes, Dict],
                 log_entry: Dict) -> Dict:
    topic = log_entry["topics"][0]
    event_abi = topic_to_event_abi[topic]

    return get_event_data(event_abi, log_entry)
def test_deprecation_executor(
    web3: Web3,
    contracts_manager: ContractManager,
    deploy_contract: Callable,
    secret_registry_contract: Contract,
    custom_token: Contract,
    channel_participant_deposit_limit: int,
    token_network_deposit_limit: int,
    get_accounts: Callable,
) -> None:
    """ A creates a TokenNetworkRegistry and B registers a TokenNetwork

    This test is mainly a happy-path scenario. One Ethereum account creates a
    TokenNetworkRegistry, registers a TokenNetwork. TokenNetworkRegistry emits
    events that shows the new TokenNetwork. The new TokenNetwork has the
    original account as the deprecation executor. During these, this test also
    tries to register more than one TokenNetworks and see a failure.
    """
    (deprecation_executor, B) = get_accounts(2)

    json_contract = contracts_manager.get_contract(
        CONTRACT_TOKEN_NETWORK_REGISTRY)
    token_network_registry = deploy_contract(
        web3,
        deprecation_executor,
        json_contract["abi"],
        json_contract["bin"],
        _secret_registry_address=secret_registry_contract.address,
        _chain_id=int(web3.version.network),
        _settlement_timeout_min=TEST_SETTLE_TIMEOUT_MIN,
        _settlement_timeout_max=TEST_SETTLE_TIMEOUT_MAX,
        _max_token_networks=1,
    )

    # Make sure deployer is deprecation_executor
    assert token_network_registry.functions.deprecation_executor().call(
    ) == deprecation_executor
    assert token_network_registry.functions.token_network_created().call() == 0

    # We can only deploy one TokenNetwork contract
    # It can be deployed by anyone
    tx_hash = token_network_registry.functions.createERC20TokenNetwork(
        custom_token.address, channel_participant_deposit_limit,
        token_network_deposit_limit).call_and_transact({"from": B})
    assert token_network_registry.functions.token_network_created().call() == 1

    # No other TokenNetworks can be deployed now
    with pytest.raises(TransactionFailed):
        token_network_registry.functions.createERC20TokenNetwork(
            custom_token.address, channel_participant_deposit_limit,
            token_network_deposit_limit).call({"from": B})
    with pytest.raises(TransactionFailed):
        token_network_registry.functions.createERC20TokenNetwork(
            custom_token.address, channel_participant_deposit_limit,
            token_network_deposit_limit).call({"from": deprecation_executor})

    tx_receipt = web3.eth.getTransactionReceipt(tx_hash)
    event_abi = contracts_manager.get_event_abi(
        CONTRACT_TOKEN_NETWORK_REGISTRY, EVENT_TOKEN_NETWORK_CREATED)
    event_data = get_event_data(event_abi, tx_receipt["logs"][0])
    token_network_address = event_data["args"]["token_network_address"]
    token_network = web3.eth.contract(
        abi=contracts_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK),
        address=token_network_address,
    )

    assert token_network.functions.deprecation_executor().call(
    ) == deprecation_executor
def test_deprecation_executor(
        web3,
        contracts_manager,
        deploy_contract,
        secret_registry_contract,
        custom_token,
        get_accounts,
):
    """ A creates a TokenNetworkRegistry and B registers a TokenNetwork

    This test is mainly a happy-path scenario. One Ethereum account creates a
    TokenNetworkRegistry, registers a TokenNetwork. TokenNetworkRegistry emits
    events that shows the new TokenNetwork. The new TokenNetwork has the
    original account as the deprecation executor. During these, this test also
    tries to register more than one TokenNetworks and see a failure.
    """
    (deprecation_executor, B) = get_accounts(2)

    json_contract = contracts_manager.get_contract(CONTRACT_TOKEN_NETWORK_REGISTRY)
    token_network_registry = deploy_contract(
        web3,
        deprecation_executor,
        json_contract['abi'],
        json_contract['bin'],
        [
            secret_registry_contract.address,
            int(web3.version.network),
            TEST_SETTLE_TIMEOUT_MIN,
            TEST_SETTLE_TIMEOUT_MAX,
        ],
    )

    # Make sure deployer is deprecation_executor
    assert token_network_registry.functions.deprecation_executor().call() == deprecation_executor
    assert token_network_registry.functions.token_network_created().call() is False

    # We can only deploy one TokenNetwork contract
    # It can be deployed by anyone
    tx_hash = token_network_registry.functions.createERC20TokenNetwork(
        custom_token.address,
    ).transact(
        {'from': B},
    )
    assert token_network_registry.functions.token_network_created().call() is True

    # No other TokenNetworks can be deployed now
    with pytest.raises(TransactionFailed):
        token_network_registry.functions.createERC20TokenNetwork(
            custom_token.address,
        ).transact(
            {'from': B},
        )
    with pytest.raises(TransactionFailed):
        token_network_registry.functions.createERC20TokenNetwork(
            custom_token.address,
        ).transact(
            {'from': deprecation_executor},
        )

    tx_receipt = web3.eth.getTransactionReceipt(tx_hash)
    event_abi = contracts_manager.get_event_abi(
        CONTRACT_TOKEN_NETWORK_REGISTRY,
        EVENT_TOKEN_NETWORK_CREATED,
    )
    event_data = get_event_data(event_abi, tx_receipt['logs'][0])
    token_network_address = event_data['args']['token_network_address']
    token_network = web3.eth.contract(
        abi=contracts_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK),
        address=token_network_address,
    )

    assert token_network.functions.deprecation_executor().call() == deprecation_executor