Exemple #1
0
def test_token(
    deploy_client,
    token_proxy,
    private_keys,
    blockchain_rpc_ports,
    web3,
):
    privkey = private_keys[1]
    address = privatekey_to_address(privkey)
    address = to_canonical_address(address)
    other_client = JSONRPCClient(
        '0.0.0.0',
        blockchain_rpc_ports[0],
        privkey,
        web3=web3,
    )
    other_token_proxy = Token(
        other_client,
        to_canonical_address(token_proxy.proxy.contract.address),
    )

    # send some funds from deployer to generated address
    transfer_funds = 100
    token_proxy.transfer(address, transfer_funds)
    assert transfer_funds == token_proxy.balance_of(address)
    allow_funds = 100
    token_proxy.approve(address, allow_funds)
    assert allow_funds == token_proxy.proxy.contract.functions.allowance(
        to_checksum_address(deploy_client.sender),
        to_checksum_address(address),
    ).call()
    other_token_proxy.transfer(deploy_client.sender, transfer_funds)
    assert token_proxy.balance_of(address) == 0
Exemple #2
0
def replay_wal(storage, token_network_identifier, partner_address, translator=None):
    all_state_changes = storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )

    state_manager = StateManager(state_transition=node.state_transition, current_state=None)
    wal = WriteAheadLog(state_manager, storage)

    for _, state_change in enumerate(all_state_changes):
        events = wal.state_manager.dispatch(state_change)

        chain_state = wal.state_manager.current_state

        channel_state = views.get_channelstate_by_token_network_and_partner(
            chain_state,
            to_canonical_address(token_network_identifier),
            to_canonical_address(partner_address),
        )

        if not channel_state:
            continue

        ###
        # Customize this to filter things further somewhere around here.
        # An example would be to add `import pdb; pdb.set_trace()`
        # and inspect the state.
        ###

        print_state_change(state_change, translator=translator)
        print_events(events, translator=translator)
Exemple #3
0
def test_token(
        deploy_client,
        token_proxy,
        private_keys,
        web3,
        contract_manager,
):
    privkey = private_keys[1]
    address = privatekey_to_address(privkey)
    address = to_canonical_address(address)
    other_client = JSONRPCClient(web3, privkey)
    other_token_proxy = Token(
        jsonrpc_client=other_client,
        token_address=to_canonical_address(token_proxy.proxy.contract.address),
        contract_manager=contract_manager,
    )

    # send some funds from deployer to generated address
    transfer_funds = 100
    token_proxy.transfer(address, transfer_funds)
    assert transfer_funds == token_proxy.balance_of(address)
    allow_funds = 100
    token_proxy.approve(address, allow_funds)
    assert allow_funds == token_proxy.proxy.contract.functions.allowance(
        to_checksum_address(deploy_client.address),
        to_checksum_address(address),
    ).call(block_identifier='latest')
    other_token_proxy.transfer(deploy_client.address, transfer_funds)
    assert token_proxy.balance_of(address) == 0
Exemple #4
0
 def from_dict(cls, data: Dict[str, Any]) -> 'ContractReceiveChannelClosed':
     return cls(
         transaction_hash=deserialize_bytes(data['transaction_hash']),
         transaction_from=to_canonical_address(data['transaction_from']),
         token_network_identifier=to_canonical_address(data['token_network_identifier']),
         channel_identifier=ChannelID(int(data['channel_identifier'])),
         block_number=BlockNumber(int(data['block_number'])),
     )
Exemple #5
0
    def from_dict(cls, data: Dict[str, Any]) -> 'ContractSendChannelBatchUnlock':
        restored = cls(
            token_address=to_canonical_address(data['token_address']),
            token_network_identifier=to_canonical_address(data['token_network_identifier']),
            channel_identifier=ChannelID(int(data['channel_identifier'])),
            participant=to_canonical_address(data['participant']),
        )

        return restored
Exemple #6
0
    def from_dict(cls, data: Dict[str, Any]) -> 'ContractSendChannelClose':
        restored = cls(
            channel_identifier=ChannelID(int(data['channel_identifier'])),
            token_address=to_canonical_address(data['token_address']),
            token_network_identifier=to_canonical_address(data['token_network_identifier']),
            balance_proof=data['balance_proof'],
        )

        return restored
Exemple #7
0
 def from_dict(cls, data: Dict[str, Any]) -> 'ContractReceiveRouteNew':
     return cls(
         transaction_hash=deserialize_bytes(data['transaction_hash']),
         token_network_identifier=to_canonical_address(data['token_network_identifier']),
         channel_identifier=ChannelID(int(data['channel_identifier'])),
         participant1=to_canonical_address(data['participant1']),
         participant2=to_canonical_address(data['participant2']),
         block_number=BlockNumber(int(data['block_number'])),
     )
Exemple #8
0
def run_smoketests(raiden_service: RaidenService, test_config: Dict, debug: bool = False):
    """ Test that the assembled raiden_service correctly reflects the configuration from the
    smoketest_genesis. """
    try:
        chain = raiden_service.chain
        assert (
            raiden_service.default_registry.address ==
            to_canonical_address(test_config['contracts']['registry_address'])
        )
        assert (
            raiden_service.default_secret_registry.address ==
            to_canonical_address(test_config['contracts']['secret_registry_address'])
        )

        token_network_added_events = raiden_service.default_registry.filter_token_added_events()
        token_addresses = [event['args']['token_address'] for event in token_network_added_events]

        assert token_addresses == [test_config['contracts']['token_address']]

        if test_config.get('transport') == 'udp':
            assert len(chain.address_to_discovery.keys()) == 1, repr(chain.address_to_discovery)
            assert (
                list(chain.address_to_discovery.keys())[0] ==
                to_canonical_address(test_config['contracts']['discovery_address'])
            )
            discovery = list(chain.address_to_discovery.values())[0]
            assert discovery.endpoint_by_address(raiden_service.address) != TEST_ENDPOINT

        token_networks = views.get_token_network_addresses_for(
            views.state_from_raiden(raiden_service),
            raiden_service.default_registry.address,
        )
        assert len(token_networks) == 1

        channel_state = views.get_channelstate_for(
            views.state_from_raiden(raiden_service),
            raiden_service.default_registry.address,
            token_networks[0],
            unhexlify(TEST_PARTNER_ADDRESS),
        )

        distributable = channel.get_distributable(
            channel_state.our_state,
            channel_state.partner_state,
        )
        assert distributable == TEST_DEPOSIT_AMOUNT
        assert distributable == channel_state.our_state.contract_balance
        assert channel.get_status(channel_state) == CHANNEL_STATE_OPENED

        # Run API test
        run_restapi_smoketests()
    except Exception:
        error = traceback.format_exc()
        if debug:
            import pdb
            pdb.post_mortem()
        return error
def test_serialization_participants_tuple():
    participants = (
        to_canonical_address('0x5522070585a1a275631ba69c444ac0451AA9Fe4C'),
        to_canonical_address('0xEF4f7c9962d8bAa8E268B72EC6DD4BDf09C84397'),
    )

    data = serialization.serialize_participants_tuple(participants)
    restored = serialization.deserialize_participants_tuple(data)

    assert participants == restored
Exemple #10
0
    def from_dict(cls, data: Dict[str, Any]) -> 'EventPaymentSentFailed':
        restored = cls(
            payment_network_identifier=to_canonical_address(data['payment_network_identifier']),
            token_network_identifier=to_canonical_address(data['token_network_identifier']),
            identifier=int(data['identifier']),
            target=to_canonical_address(data['target']),
            reason=data['reason'],
        )

        return restored
Exemple #11
0
    def from_dict(cls, data: Dict[str, Any]) -> 'EventPaymentReceivedSuccess':
        restored = cls(
            payment_network_identifier=to_canonical_address(data['payment_network_identifier']),
            token_network_identifier=to_canonical_address(data['token_network_identifier']),
            identifier=int(data['identifier']),
            amount=int(data['amount']),
            initiator=to_canonical_address(data['initiator']),
        )

        return restored
Exemple #12
0
def normalize_exec(exec_params):
    return {
        'origin': to_canonical_address(exec_params['origin']),
        'address': to_canonical_address(exec_params['address']),
        'caller': to_canonical_address(exec_params['caller']),
        'value': to_int(exec_params['value']),
        'data': decode_hex(exec_params['data']),
        'gas': to_int(exec_params['gas']),
        'gasPrice': to_int(exec_params['gasPrice']),
    }
Exemple #13
0
    def from_dict(cls, data: typing.Dict[str, typing.Any]) -> 'LockedTransferUnsignedState':
        restored = cls(
            payment_identifier=int(data['payment_identifier']),
            token=to_canonical_address(data['token']),
            balance_proof=data['balance_proof'],
            lock=data['lock'],
            initiator=to_canonical_address(data['initiator']),
            target=to_canonical_address(data['target']),
        )

        return restored
Exemple #14
0
 def from_dict(cls, data: Dict[str, Any]) -> 'ContractReceiveChannelBatchUnlock':
     return cls(
         transaction_hash=deserialize_bytes(data['transaction_hash']),
         token_network_identifier=to_canonical_address(data['token_network_identifier']),
         participant=to_canonical_address(data['participant']),
         partner=to_canonical_address(data['partner']),
         locksroot=deserialize_bytes(data['locksroot']),
         unlocked_amount=int(data['unlocked_amount']),
         returned_tokens=int(data['returned_tokens']),
         block_number=BlockNumber(int(data['block_number'])),
     )
Exemple #15
0
    def from_dict(cls, data: Dict[str, Any]) -> 'SendBalanceProof':
        restored = cls(
            recipient=to_canonical_address(data['recipient']),
            channel_identifier=ChannelID(int(data['channel_identifier'])),
            message_identifier=MessageID(int(data['message_identifier'])),
            payment_identifier=PaymentID(int(data['payment_identifier'])),
            token_address=to_canonical_address(data['token_address']),
            secret=Secret(serialization.deserialize_bytes(data['secret'])),
            balance_proof=data['balance_proof'],
        )

        return restored
Exemple #16
0
    def from_dict(cls, data: typing.Dict[str, typing.Any]) -> 'TransferDescriptionWithSecretState':
        restored = cls(
            payment_network_identifier=to_canonical_address(data['payment_network_identifier']),
            payment_identifier=int(data['payment_identifier']),
            amount=int(data['amount']),
            token_network_identifier=to_canonical_address(data['token_network_identifier']),
            initiator=to_canonical_address(data['initiator']),
            target=to_canonical_address(data['target']),
            secret=serialization.deserialize_bytes(data['secret']),
        )

        return restored
def test_serialization_networkx_graph():
    p1 = to_canonical_address('0x5522070585a1a275631ba69c444ac0451AA9Fe4C')
    p2 = to_canonical_address('0x5522070585a1a275631ba69c444ac0451AA9Fe4D')
    p3 = to_canonical_address('0x5522070585a1a275631ba69c444ac0451AA9Fe4E')
    p4 = to_canonical_address('0x5522070585a1a275631ba69c444ac0451AA9Fe4F')

    e = [(p1, p2), (p2, p3), (p3, p4)]
    graph = Graph(e)

    data = serialization.serialize_networkx_graph(graph)
    restored_graph = serialization.deserialize_networkx_graph(data)

    assert graph.edges == restored_graph.edges
def test_encode_address(address_value, value_bit_size, data_byte_size):
    if value_bit_size != 20 * 8:
        with pytest.raises(ValueError):
            AddressEncoder(
                value_bit_size=value_bit_size,
                data_byte_size=data_byte_size,
            )
        return
    elif value_bit_size > data_byte_size * 8:
        with pytest.raises(ValueError):
            AddressEncoder(
                value_bit_size=value_bit_size,
                data_byte_size=data_byte_size,
            )
        return

    encoder = AddressEncoder(
        value_bit_size=value_bit_size,
        data_byte_size=data_byte_size,
    )

    if not is_address(address_value):
        with pytest.raises(EncodingTypeError) as exception_info:
            encoder(address_value)
        assert 'AddressEncoder' in str(exception_info.value)
        return

    expected_value = zpad(to_canonical_address(address_value), data_byte_size)
    encoded_value = encoder(address_value)

    assert encoded_value == expected_value
Exemple #19
0
    def send_transaction(
            self,
            to: Address,
            value: int = 0,
            data: bytes = b'',
            startgas: int = None,
            gasprice: int = None,
    ):
        """ Helper to send signed messages.

        This method will use the `privkey` provided in the constructor to
        locally sign the transaction. This requires an extended server
        implementation that accepts the variables v, r, and s.
        """
        if to == to_canonical_address(NULL_ADDRESS):
            warnings.warn('For contract creation the empty string must be used.')

        transaction = dict(
            nonce=self.nonce(),
            gasPrice=gasprice or self.gasprice(),
            gas=self.check_startgas(startgas),
            value=value,
            data=data,
        )

        # add the to address if not deploying a contract
        if to != b'':
            transaction['to'] = to_checksum_address(to)

        signed_txn = self.web3.eth.account.signTransaction(transaction, self.privkey)

        result = self.web3.eth.sendRawTransaction(signed_txn.rawTransaction)
        encoded_result = encode_hex(result)
        return remove_0x_prefix(encoded_result)
Exemple #20
0
    def poll_blockchain_events(self, block_number: int = None):
        # When we test with geth if the contracts have already been deployed
        # before the filter creation we need to use `get_all_entries` to make
        # sure we get all the events. With tester this is not required.

        for event_listener in self.event_listeners:
            if isinstance(event_listener.filter, StatelessFilter):
                events = event_listener.filter.get_new_entries(block_number)
            elif event_listener.first_run is True:
                events = event_listener.filter.get_all_entries()
                index = self.event_listeners.index(event_listener)
                self.event_listeners[index] = event_listener._replace(first_run=False)
            else:
                events = event_listener.filter.get_new_entries()

            for log_event in events:
                decoded_event = dict(decode_event(
                    event_listener.abi,
                    log_event,
                ))

                if decoded_event is not None:
                    decoded_event['block_number'] = log_event.get('blockNumber', 0)
                    event = Event(
                        to_canonical_address(log_event['address']),
                        decoded_event,
                    )
                    yield decode_event_to_internal(event)
Exemple #21
0
def state_change_with_nonce(obj, nonce, channel_identifier, sender):
    return (
        hasattr(obj, 'balance_proof') and
        obj.balance_proof.nonce == nonce and
        obj.balance_proof.channel_identifier == channel_identifier and
        obj.balance_proof.sender == to_canonical_address(sender)
    )
Exemple #22
0
 def from_dict(cls, data) -> 'ReceiveSecretReveal':
     instance = cls(
         secret=deserialize_bytes(data['secret']),
         sender=to_canonical_address(data['sender']),
     )
     instance.secrethash = deserialize_bytes(data['secrethash'])
     return instance
Exemple #23
0
 def from_dict(cls, data: Dict[str, Any]) -> 'ContractReceiveNewTokenNetwork':
     return cls(
         transaction_hash=deserialize_bytes(data['transaction_hash']),
         payment_network_identifier=to_canonical_address(data['payment_network_identifier']),
         token_network=data['token_network'],
         block_number=BlockNumber(int(data['block_number'])),
     )
def transform_records(log_records: Iterable[Record], replacements: Dict[str, Any]):
    def replace(value):
        # Use `type(value)()` construction to preserve exact (sub-)type
        if isinstance(value, tuple) and hasattr(value, '_fields'):
            # namedtuples have a different signature, *sigh*
            return type(value)(*[replace(inner) for inner in value])
        if isinstance(value, (list, tuple)):
            return type(value)(replace(inner) for inner in value)
        elif isinstance(value, dict):
            return {
                replace(k): replace(v)
                for k, v in value.items()
            }
        str_value = str(value).lower()
        if isinstance(value, str):
            keys_in_value = [key for key in replacement_keys if key in str_value]
            for key in keys_in_value:
                try:
                    repl_start = str_value.index(key)
                except ValueError:
                    # Value no longer in string due to replacement
                    continue
                value = f"{value[:repl_start]}{replacements[key]}{value[repl_start + len(key):]}"
                str_value = value.lower()
        return replacements.get(str_value, value)

    replacements = {str(k).lower(): v for k, v in replacements.items()}
    for k, v in copy(replacements).items():
        # Special handling for `pex()`ed eth addresses
        if isinstance(k, str) and k.startswith('0x') and is_address(k):
            replacements[pex(to_canonical_address(k))] = v
    replacement_keys = replacements.keys()
    for record in log_records:
        yield replace(record)
Exemple #25
0
 def from_dict(cls, data):
     assert data['type'] == cls.__name__
     expired_lock = cls(
         chain_id=data['chain_id'],
         nonce=data['nonce'],
         message_identifier=data['message_identifier'],
         token_network_address=to_canonical_address(data['token_network_address']),
         channel_identifier=data['channel_identifier'],
         transferred_amount=data['transferred_amount'],
         secrethash=decode_hex(data['secrethash']),
         recipient=to_canonical_address(data['recipient']),
         locked_amount=data['locked_amount'],
         locksroot=decode_hex(data['locksroot']),
     )
     expired_lock.signature = decode_hex(data['signature'])
     return expired_lock
Exemple #26
0
    def address_by_endpoint(self, endpoint):
        address = self.proxy.contract.functions.findAddressByEndpoint(endpoint).call()

        if address == self.not_found_address:  # the 0 address means nothing found
            return None

        return to_canonical_address(address)
Exemple #27
0
def normalize_block_header(header):
    normalized_header = {
        'bloom': big_endian_to_int(decode_hex(header['bloom'])),
        'coinbase': to_canonical_address(header['coinbase']),
        'difficulty': to_int(header['difficulty']),
        'extraData': decode_hex(header['extraData']),
        'gasLimit': to_int(header['gasLimit']),
        'gasUsed': to_int(header['gasUsed']),
        'hash': decode_hex(header['hash']),
        'mixHash': decode_hex(header['mixHash']),
        'nonce': decode_hex(header['nonce']),
        'number': to_int(header['number']),
        'parentHash': decode_hex(header['parentHash']),
        'receiptTrie': decode_hex(header['receiptTrie']),
        'stateRoot': decode_hex(header['stateRoot']),
        'timestamp': to_int(header['timestamp']),
        'transactionsTrie': decode_hex(header['transactionsTrie']),
        'uncleHash': decode_hex(header['uncleHash']),
    }
    if 'blocknumber' in header:
        normalized_header['blocknumber'] = to_int(header['blocknumber'])
    if 'chainname' in header:
        normalized_header['chainname'] = header['chainname']
    if 'chainnetwork' in header:
        normalized_header['chainnetwork'] = header['chainnetwork']
    return normalized_header
Exemple #28
0
    def from_dict(cls, data: Dict[str, Any]) -> 'ContractSendChannelSettle':
        restored = cls(
            channel_identifier=ChannelID(int(data['channel_identifier'])),
            token_network_identifier=to_canonical_address(data['token_network_identifier']),
        )

        return restored
Exemple #29
0
def decode_event_to_internal(event):
    """ Enforce the binary encoding of address for internal usage. """
    data = event.event_data

    if data['args'].get('channel_identifier'):
        data['channel_identifier'] = data['args'].get('channel_identifier')

    # Note: All addresses inside the event_data must be decoded.
    if data['event'] == EVENT_TOKEN_NETWORK_CREATED:
        data['token_network_address'] = to_canonical_address(data['args']['token_network_address'])
        data['token_address'] = to_canonical_address(data['args']['token_address'])

    elif data['event'] == EVENT_CHANNEL_OPENED:
        data['participant1'] = to_canonical_address(data['args']['participant1'])
        data['participant2'] = to_canonical_address(data['args']['participant2'])
        data['settle_timeout'] = data['args']['settle_timeout']

    elif data['event'] == EVENT_CHANNEL_DEPOSIT:
        data['deposit'] = data['args']['total_deposit']
        data['participant'] = to_canonical_address(data['args']['participant'])

    elif data['event'] == EVENT_CHANNEL_WITHDRAW:
        data['withdrawn_amount'] = data['args']['withdrawn_amount']
        data['participant'] = to_canonical_address(data['args']['participant'])

    elif data['event'] == EVENT_CHANNEL_BALANCE_PROOF_UPDATED:
        data['closing_participant'] = to_canonical_address(data['args']['closing_participant'])

    elif data['event'] == EVENT_CHANNEL_CLOSED:
        data['closing_participant'] = to_canonical_address(data['args']['closing_participant'])

    elif data['event'] == EVENT_CHANNEL_SETTLED:
        data['participant1_amount'] = data['args']['participant1_amount']
        data['participant2_amount'] = data['args']['participant2_amount']

    elif data['event'] == EVENT_CHANNEL_UNLOCKED:
        data['unlocked_amount'] = data['args']['unlocked_amount']
        data['returned_tokens'] = data['args']['returned_tokens']
        data['participant'] = to_canonical_address(data['args']['participant'])
        data['partner'] = to_canonical_address(data['args']['partner'])
        data['locksroot'] = data['args']['locksroot']

    elif data['event'] == EVENT_SECRET_REVEALED:
        data['secrethash'] = data['args']['secrethash']
        data['secret'] = data['args']['secret']

    return event
Exemple #30
0
 def from_dict(cls, data):
     assert data['type'] == cls.__name__
     direct_transfer = cls(
         chain_id=data['chain_id'],
         message_identifier=data['message_identifier'],
         payment_identifier=data['payment_identifier'],
         nonce=data['nonce'],
         token_network_address=to_canonical_address(data['token_network_address']),
         token=to_canonical_address(data['token']),
         channel_identifier=decode_hex(data['channel']),
         transferred_amount=data['transferred_amount'],
         recipient=to_canonical_address(data['recipient']),
         locked_amount=data['locked_amount'],
         locksroot=decode_hex(data['locksroot']),
     )
     direct_transfer.signature = decode_hex(data['signature'])
     return direct_transfer
Exemple #31
0
def chain():
    """
    Return a Chain object containing just the genesis block.

    The Chain's state includes one funded account, which can be found in the funded_address in the
    chain itself.

    This Chain will perform all validations when importing new blocks, so only valid and finalized
    blocks can be used with it. If you want to test importing arbitrarily constructe, not
    finalized blocks, use the chain_without_block_validation fixture instead.
    """
    genesis_params = {
        "bloom":
        0,
        "coinbase":
        to_canonical_address("8888f1f195afa192cfee860698584c030f4c9db1"),
        "difficulty":
        131072,
        "extra_data":
        b"B",
        "gas_limit":
        3141592,
        "gas_used":
        0,
        "mix_hash":
        decode_hex(
            "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
        ),
        "nonce":
        decode_hex("0102030405060708"),
        "block_number":
        0,
        "parent_hash":
        decode_hex(
            "0000000000000000000000000000000000000000000000000000000000000000"
        ),
        "receipt_root":
        decode_hex(
            "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
        ),
        "state_root":
        decode_hex(
            "cafd881ab193703b83816c49ff6c2bf6ba6f464a1be560c42106128c8dbc35e7"
        ),
        "timestamp":
        1422494849,
        "transaction_root":
        decode_hex(
            "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
        ),
        "uncles_hash":
        decode_hex(
            "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")
    }
    funded_addr = to_canonical_address(
        "a94f5374fce5edbc8e2a8697c15331677e6ebf0b")
    initial_balance = 10000000000
    genesis_state = {
        funded_addr: {
            "balance": initial_balance,
            "nonce": 0,
            "code": b"",
            "storage": {}
        }
    }
    klass = Chain.configure(name='TestChain',
                            vm_configuration=((constants.GENESIS_BLOCK_NUMBER,
                                               FrontierVM), ))
    chain = klass.from_genesis(BaseChainDB(get_db_backend()), genesis_params,
                               genesis_state)
    chain.funded_address = funded_addr
    chain.funded_address_initial_balance = initial_balance
    return chain
Exemple #32
0
 def from_dict(cls, data) -> 'ActionNewTokenNetwork':
     return cls(
         payment_network_identifier=to_canonical_address(data['payment_network_identifier']),
         token_network=data['token_network'],
     )
Exemple #33
0
ROPSTEN = 'ropsten'
RINKEBY = 'rinkeby'
KOVAN = 'kovan'
SMOKETEST = 'smoketest'

ID_TO_NETWORKNAME = {
    1: MAINNET,
    3: ROPSTEN,
    4: RINKEBY,
    42: KOVAN,
    627: SMOKETEST,
}

ID_TO_NETWORK_CONFIG = {
    3: {
        CONTRACT_ENDPOINT_REGISTRY: to_canonical_address(ROPSTEN_DISCOVERY_ADDRESS),
        CONTRACT_SECRET_REGISTRY: to_canonical_address(ROPSTEN_SECRET_REGISTRY_ADDRESS),
        CONTRACT_TOKEN_NETWORK_REGISTRY: to_canonical_address(ROPSTEN_REGISTRY_ADDRESS),
        START_QUERY_BLOCK_KEY: 3604000,  # 924 blocks before token network registry deployment
    },
}

NETWORKNAME_TO_ID = {
    name: id
    for id, name in ID_TO_NETWORKNAME.items()
}

MIN_REQUIRED_SOLC = 'v0.4.23'
NULL_ADDRESS = '0x' + '0' * 40
NULL_ADDRESS_BYTES = b'\x00' * 20
def test_token_network_proxy_basics(
    token_network_proxy,
    private_keys,
    token_proxy,
    chain_id,
    web3,
    contract_manager,
):
    # check settlement timeouts
    assert token_network_proxy.settlement_timeout_min(
    ) == TEST_SETTLE_TIMEOUT_MIN
    assert token_network_proxy.settlement_timeout_max(
    ) == TEST_SETTLE_TIMEOUT_MAX

    token_network_address = to_canonical_address(
        token_network_proxy.proxy.contract.address)

    c1_client = JSONRPCClient(web3, private_keys[1])
    c1_chain = BlockChainService(private_keys[1], c1_client)
    c2_client = JSONRPCClient(web3, private_keys[2])
    c1_token_network_proxy = TokenNetwork(
        jsonrpc_client=c1_client,
        token_network_address=token_network_address,
        contract_manager=contract_manager,
    )
    c2_token_network_proxy = TokenNetwork(
        jsonrpc_client=c2_client,
        token_network_address=token_network_address,
        contract_manager=contract_manager,
    )

    initial_token_balance = 100
    token_proxy.transfer(c1_client.address, initial_token_balance)
    token_proxy.transfer(c2_client.address, initial_token_balance)
    initial_balance_c1 = token_proxy.balance_of(c1_client.address)
    assert initial_balance_c1 == initial_token_balance
    initial_balance_c2 = token_proxy.balance_of(c2_client.address)
    assert initial_balance_c2 == initial_token_balance

    # instantiating a new channel - test basic assumptions
    assert c1_token_network_proxy.channel_exists_and_not_settled(
        c1_client.address,
        c2_client.address,
    ) is False

    channel_identifier = c1_token_network_proxy._call_and_check_result(
        'latest',
        'getChannelIdentifier',
        to_checksum_address(c1_client.address),
        to_checksum_address(c2_client.address),
    )
    assert c1_token_network_proxy.channel_is_opened(
        c1_client.address,
        c2_client.address,
        channel_identifier,
    ) is False
    assert c1_token_network_proxy.channel_is_closed(
        c1_client.address,
        c2_client.address,
        channel_identifier,
    ) is False
    # test timeout limits
    with pytest.raises(InvalidSettleTimeout):
        c1_token_network_proxy.new_netting_channel(
            c2_client.address,
            TEST_SETTLE_TIMEOUT_MIN - 1,
        )
    with pytest.raises(InvalidSettleTimeout):
        c1_token_network_proxy.new_netting_channel(
            c2_client.address,
            TEST_SETTLE_TIMEOUT_MAX + 1,
        )
    # channel to self
    with pytest.raises(SamePeerAddress):
        c1_token_network_proxy.new_netting_channel(
            c1_client.address,
            TEST_SETTLE_TIMEOUT_MIN,
        )

    # Channel is not open yet
    with pytest.raises(RaidenUnrecoverableError) as exc:
        c1_token_network_proxy.set_total_deposit(
            1,
            1,
            c2_client.address,
        )

        assert 'does not exist' in str(exc)

    # Channel is not open yet
    with pytest.raises(RaidenUnrecoverableError) as exc:
        c1_token_network_proxy.close(
            1,
            c2_client.address,
            EMPTY_HASH,
            0,
            EMPTY_HASH,
            EMPTY_HASH,
        )

        assert 'does not exist' in str(exc)

    # actually create a channel
    channel_identifier = c1_token_network_proxy.new_netting_channel(
        c2_client.address,
        TEST_SETTLE_TIMEOUT_MIN,
    )
    assert channel_identifier is not None
    # multiple channels with the same peer are not allowed
    with pytest.raises(DuplicatedChannelError):
        c1_token_network_proxy.new_netting_channel(
            c2_client.address,
            TEST_SETTLE_TIMEOUT_MIN,
        )
    assert c1_token_network_proxy.channel_exists_and_not_settled(
        participant1=c1_client.address,
        participant2=c2_client.address,
        channel_identifier=channel_identifier,
    ) is True
    assert c1_token_network_proxy.channel_is_opened(
        participant1=c1_client.address,
        participant2=c2_client.address,
        channel_identifier=channel_identifier,
    ) is True

    # channel is open.
    # deposit with no balance
    with pytest.raises(DepositMismatch):
        c1_token_network_proxy.set_total_deposit(
            channel_identifier,
            101,
            c2_client.address,
        )

    # no negative deposit
    with pytest.raises(DepositMismatch):
        c1_token_network_proxy.set_total_deposit(
            channel_identifier,
            -1,
            c2_client.address,
        )
    # actual deposit
    c1_token_network_proxy.set_total_deposit(
        channel_identifier,
        10,
        c2_client.address,
    )

    # balance proof by c2
    transferred_amount = 3
    balance_proof = BalanceProof(
        channel_identifier=channel_identifier,
        token_network_address=to_checksum_address(token_network_address),
        nonce=1,
        chain_id=chain_id,
        transferred_amount=transferred_amount,
    )
    balance_proof.signature = encode_hex(
        eth_sign(
            privkey=encode_hex(private_keys[1]),
            data=balance_proof.serialize_bin(),
        ))
    # close with invalid signature
    with pytest.raises(RaidenUnrecoverableError):
        c2_token_network_proxy.close(
            channel_identifier=channel_identifier,
            partner=c1_client.address,
            balance_hash=decode_hex(balance_proof.balance_hash),
            nonce=balance_proof.nonce,
            additional_hash=decode_hex(balance_proof.additional_hash),
            signature=b'\x11' * 65,
        )

    # correct close
    c2_token_network_proxy.close(
        channel_identifier=channel_identifier,
        partner=c1_client.address,
        balance_hash=decode_hex(balance_proof.balance_hash),
        nonce=balance_proof.nonce,
        additional_hash=decode_hex(balance_proof.additional_hash),
        signature=decode_hex(balance_proof.signature),
    )
    assert c1_token_network_proxy.channel_is_closed(
        participant1=c1_client.address,
        participant2=c2_client.address,
        channel_identifier=channel_identifier,
    ) is True
    assert c1_token_network_proxy.channel_exists_and_not_settled(
        participant1=c1_client.address,
        participant2=c2_client.address,
        channel_identifier=channel_identifier,
    ) is True

    # closing already closed channel
    with pytest.raises(RaidenRecoverableError):
        c2_token_network_proxy.close(
            channel_identifier=channel_identifier,
            partner=c1_client.address,
            balance_hash=decode_hex(balance_proof.balance_hash),
            nonce=balance_proof.nonce,
            additional_hash=decode_hex(balance_proof.additional_hash),
            signature=decode_hex(balance_proof.signature),
        )

    with pytest.raises(RaidenRecoverableError) as exc:
        c2_token_network_proxy.set_total_deposit(
            channel_identifier,
            20,
            c1_client.address,
        )

        assert 'not in an open state' in str(exc)

    with pytest.raises(RaidenRecoverableError) as exc:
        c2_token_network_proxy.close(
            channel_identifier=channel_identifier,
            partner=c1_client.address,
            balance_hash=decode_hex(balance_proof.balance_hash),
            nonce=balance_proof.nonce,
            additional_hash=decode_hex(balance_proof.additional_hash),
            signature=decode_hex(balance_proof.signature),
        )

        assert 'not in an open state' in str(exc)

    # update transfer
    wait_until_block(c1_chain,
                     c1_chain.block_number() + TEST_SETTLE_TIMEOUT_MIN)

    # try to settle using incorrect data
    with pytest.raises(RaidenUnrecoverableError):
        c2_token_network_proxy.settle(
            channel_identifier=channel_identifier,
            transferred_amount=1,
            locked_amount=0,
            locksroot=EMPTY_HASH,
            partner=c1_client.address,
            partner_transferred_amount=transferred_amount,
            partner_locked_amount=0,
            partner_locksroot=EMPTY_HASH,
        )

    c2_token_network_proxy.settle(
        channel_identifier=channel_identifier,
        transferred_amount=0,
        locked_amount=0,
        locksroot=EMPTY_HASH,
        partner=c1_client.address,
        partner_transferred_amount=transferred_amount,
        partner_locked_amount=0,
        partner_locksroot=EMPTY_HASH,
    )
    assert c1_token_network_proxy.channel_exists_and_not_settled(
        participant1=c1_client.address,
        participant2=c2_client.address,
        channel_identifier=channel_identifier,
    ) is False
    assert token_proxy.balance_of(c1_client.address) == (initial_balance_c1 -
                                                         transferred_amount)
    assert token_proxy.balance_of(c2_client.address) == (initial_balance_c2 +
                                                         transferred_amount)

    with pytest.raises(RaidenUnrecoverableError) as exc:
        c1_token_network_proxy.set_total_deposit(
            channel_identifier,
            10,
            c2_client.address,
        )
        # No channel exists
        assert 'getChannelIdentifier returned 0' in str(exc)
Exemple #35
0
def _generate_dummy_address(idx):
    return to_canonical_address(
        decode_hex('0xabbacadaba') + zpad(int_to_big_endian(idx), 15))
Exemple #36
0
 def mock_login(user, pw, sync=True):  # pylint: disable=unused-argument
     recovered = recover(data=server_name.encode(),
                         signature=decode_hex(pw))
     if recovered != to_canonical_address(user):
         raise MatrixRequestError(403)
     client.user_id = f"@{user}:{server_name}"
Exemple #37
0
def secret_registry_proxy(deploy_client, secret_registry_contract):
    return SecretRegistry(
        deploy_client,
        to_canonical_address(secret_registry_contract.contract.address),
    )
Exemple #38
0
def withdraw_from_udc(
    reclamation_candidates: List[ReclamationCandidate],
    contract_manager: ContractManager,
    account: Account,
    web3: Web3,
    development_environment: ContractDevEnvironment,
):
    chain_id = ChainID(web3.eth.chainId)
    deploy = get_contracts_deployment_info(
        chain_id,
        RAIDEN_CONTRACT_VERSION,
        development_environment=development_environment)
    assert deploy

    planned_withdraws: Dict[ChecksumAddress, Tuple[BlockNumber,
                                                   TokenAmount]] = {}

    log.info("Checking chain for deposits in UserDeposit contact")
    for node in reclamation_candidates:
        (userdeposit_proxy,
         _) = get_udc_and_corresponding_token_from_dependencies(
             chain_id=chain_id,
             proxy_manager=node.get_proxy_manager(web3, deploy),
             development_environment=development_environment,
         )

        balance = userdeposit_proxy.get_total_deposit(
            to_canonical_address(node.address), "latest")
        log.debug("UDC balance", balance=balance, address=node.address)
        if balance > 0:
            drain_amount = TokenAmount(balance)
            existing_plan = userdeposit_proxy.get_withdraw_plan(
                to_canonical_address(node.address), "latest")
            if existing_plan.withdraw_amount == drain_amount:
                log.info(
                    "Withdraw already planned",
                    from_address=node.address,
                    amount=drain_amount.__format__(",d"),
                )
                ready_at_block = existing_plan.withdraw_block
            else:
                log.info(
                    "Planning withdraw",
                    from_address=node.address,
                    amount=drain_amount.__format__(",d"),
                )
                try:
                    _, ready_at_block = userdeposit_proxy.plan_withdraw(
                        drain_amount, "latest")
                except InsufficientEth:
                    log.warning(
                        "Not sufficient eth in node wallet to withdraw",
                        address=node.address,
                    )
                    continue
            planned_withdraws[node.address] = ready_at_block, drain_amount

    if not planned_withdraws:
        return

    log.info(
        "Withdraws successfully planned, waiting until withdraws are ready",
        planned_withdraws=planned_withdraws,
    )

    reclaim_amount = 0
    for address, (ready_at_block, amount) in planned_withdraws.items():
        candidate = [
            c for c in reclamation_candidates if c.address == address
        ][0]
        proxy_manager = candidate.get_proxy_manager(web3, deploy)
        (userdeposit_proxy,
         _) = get_udc_and_corresponding_token_from_dependencies(
             chain_id=chain_id,
             proxy_manager=proxy_manager,
             development_environment=development_environment,
         )
        # FIXME: Something is off with the block numbers, adding 20 to work around.
        #        See https://github.com/raiden-network/raiden/pull/6091/files#r412234516
        proxy_manager.client.wait_until_block(BlockNumber(ready_at_block + 20),
                                              retry_timeout=10)

        log.info("Withdraw",
                 user_address=address,
                 amount=amount.__format__(",d"))
        reclaim_amount += amount
        userdeposit_proxy.withdraw(amount, "latest")

    log.info(
        "All UDC withdraws finished, now claim the resulting tokens!",
        withdraw_total=reclaim_amount.__format__(",d"),
    )

    reclaim_erc20(
        reclamation_candidates,
        userdeposit_proxy.token_address("latest"),
        contract_manager,
        account,
        web3,
    )
Exemple #39
0
def _withdraw_participant_left_capacity_from_channel(
    address_to_candidate: Dict[Address, ReclamationCandidate],
    channel: dict,
    token_network: TokenNetwork,
    current_confirmed_head: BlockIdentifier,
) -> None:
    """ Withdraw all tokens in channel to channel["participant1"] """
    assert token_network.client.address == channel["participant1"]

    # Check if channel still has deposits
    details = token_network.detail_participants(
        participant1=to_canonical_address(channel["participant1"]),
        participant2=to_canonical_address(channel["participant2"]),
        block_identifier=current_confirmed_head,
        channel_identifier=channel["channel_identifier"],
    )
    new_withdraw = WithdrawAmount(details.our_details.deposit -
                                  details.our_details.withdrawn +
                                  details.partner_details.deposit -
                                  details.partner_details.withdrawn)
    assert new_withdraw >= 0, "negative withdrawn should never happen."

    if new_withdraw == 0:
        log.info(
            "Participant has no left over capacity in the channel. Skipping channel.",
            channel=channel,
        )
        return

    partner_candidate = address_to_candidate.get(
        details.partner_details.address)
    if partner_candidate is None:
        log.error(
            "Both participants must be in list of reclamation_candidates. Skipping channel.",
            channel=channel,
        )
        return

    expiration_block = BlockExpiration(100000000000000)
    total_withdraw = WithdrawAmount(details.our_details.withdrawn +
                                    new_withdraw)
    packed_withdraw = pack_withdraw(
        canonical_identifier=CanonicalIdentifier(
            chain_identifier=token_network.chain_id(),
            token_network_address=token_network.address,
            channel_identifier=channel["channel_identifier"],
        ),
        participant=to_canonical_address(channel["participant1"]),
        total_withdraw=total_withdraw,
        expiration_block=expiration_block,
    )

    privkey = token_network.client.privkey
    try:
        token_network.set_total_withdraw(
            given_block_identifier=current_confirmed_head,
            channel_identifier=channel["channel_identifier"],
            total_withdraw=total_withdraw,
            expiration_block=expiration_block,
            participant=to_canonical_address(channel["participant1"]),
            partner=to_canonical_address(channel["participant2"]),
            participant_signature=LocalSigner(privkey).sign(packed_withdraw),
            partner_signature=LocalSigner(
                partner_candidate.privkey).sign(packed_withdraw),
        )
    except InsufficientEth:
        log.warning("Not enough ETH to withdraw", channel=channel)
    else:
        log.info("Withdraw successful", channel=channel, amount=new_withdraw)
Exemple #40
0
def app(
    address,
    keystore_path,
    gas_price,
    eth_rpc_endpoint,
    registry_contract_address,
    secret_registry_contract_address,
    discovery_contract_address,
    listen_address,
    rpccorsdomain,
    mapped_socket,
    log_config,
    log_file,
    log_json,
    max_unresponsive_time,
    send_ping_time,
    api_address,
    rpc,
    sync_check,
    console,
    password_file,
    web_ui,
    datadir,
    nat,
    transport,
    matrix_server,
    network_id,
    config_file,
    extra_config=None,
):
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements,unused-argument

    from raiden.app import App

    if transport == 'udp' and not mapped_socket:
        raise RuntimeError('Missing socket')

    address_hex = to_normalized_address(address) if address else None
    address_hex, privatekey_bin = prompt_account(address_hex, keystore_path,
                                                 password_file)
    address = to_canonical_address(address_hex)

    (listen_host, listen_port) = split_endpoint(listen_address)
    (api_host, api_port) = split_endpoint(api_address)

    if datadir is None:
        datadir = os.path.join(os.path.expanduser('~'), '.raiden')

    config = deepcopy(App.DEFAULT_CONFIG)
    if extra_config:
        merge_dict(config, extra_config)

    config['host'] = listen_host
    config['port'] = listen_port
    config['console'] = console
    config['rpc'] = rpc
    config['web_ui'] = rpc and web_ui
    config['api_host'] = api_host
    config['api_port'] = api_port
    if mapped_socket:
        config['socket'] = mapped_socket.socket
        config['external_ip'] = mapped_socket.external_ip
        config['external_port'] = mapped_socket.external_port
    config['transport_type'] = transport
    config['matrix']['server'] = matrix_server
    config['transport'][
        'nat_keepalive_retries'] = DEFAULT_NAT_KEEPALIVE_RETRIES
    timeout = max_unresponsive_time / DEFAULT_NAT_KEEPALIVE_RETRIES
    config['transport']['nat_keepalive_timeout'] = timeout

    privatekey_hex = hexlify(privatekey_bin)
    config['privatekey_hex'] = privatekey_hex

    rpc_host, rpc_port = eth_endpoint_to_hostport(eth_rpc_endpoint)

    rpc_client = JSONRPCClient(
        rpc_host,
        rpc_port,
        privatekey_bin,
        gas_price,
    )

    blockchain_service = BlockChainService(privatekey_bin, rpc_client)

    net_id = blockchain_service.network_id
    if net_id != network_id:
        if network_id in constants.ID_TO_NETWORKNAME and net_id in constants.ID_TO_NETWORKNAME:
            print((
                "The chosen ethereum network '{}' differs from the ethereum client '{}'. "
                'Please update your settings.').format(
                    constants.ID_TO_NETWORKNAME[network_id],
                    constants.ID_TO_NETWORKNAME[net_id]))
        else:
            print((
                "The chosen ethereum network id '{}' differs from the ethereum client '{}'. "
                'Please update your settings.').format(network_id, net_id))
        sys.exit(1)

    config['chain_id'] = network_id

    if sync_check:
        check_synced(blockchain_service)

    database_path = os.path.join(datadir, 'netid_%s' % net_id, address_hex[:8],
                                 'log.db')
    config['database_path'] = database_path
    print(
        'You are connected to the \'{}\' network and the DB path is: {}'.
        format(
            constants.ID_TO_NETWORKNAME.get(net_id) or net_id,
            database_path,
        ), )

    try:
        token_network_registry = blockchain_service.token_network_registry(
            registry_contract_address, )
    except ContractVersionMismatch:
        print(
            'Deployed registry contract version mismatch. '
            'Please update your Raiden installation.', )
        sys.exit(1)

    try:
        secret_registry = blockchain_service.secret_registry(
            secret_registry_contract_address, )
    except ContractVersionMismatch:
        print(
            'Deployed secret registry contract version mismatch. '
            'Please update your Raiden installation.', )
        sys.exit(1)

    discovery = None
    if transport == 'udp':
        check_discovery_registration_gas(blockchain_service, address)
        try:
            discovery = ContractDiscovery(
                blockchain_service.node_address,
                blockchain_service.discovery(discovery_contract_address),
            )
        except ContractVersionMismatch:
            print('Deployed discovery contract version mismatch. '
                  'Please update your Raiden installation.')
            sys.exit(1)
        throttle_policy = TokenBucket(
            config['transport']['throttle_capacity'],
            config['transport']['throttle_fill_rate'],
        )

        transport = UDPTransport(
            discovery,
            mapped_socket.socket,
            throttle_policy,
            config['transport'],
        )
    elif transport == 'matrix':
        # matrix gets spammed with the default retry-interval of 1s, wait a little more
        if config['transport'][
                'retry_interval'] == DEFAULT_TRANSPORT_RETRY_INTERVAL:
            config['transport']['retry_interval'] *= 5
        try:
            transport = MatrixTransport(config['matrix'])
        except RaidenError as ex:
            click.secho(f'FATAL: {ex}', fg='red')
            sys.exit(1)
    else:
        raise RuntimeError(f'Unknown transport type "{transport}" given')

    try:
        raiden_app = App(
            config=config,
            chain=blockchain_service,
            query_start_block=constants.ID_TO_QUERY_BLOCK[net_id],
            default_registry=token_network_registry,
            default_secret_registry=secret_registry,
            transport=transport,
            discovery=discovery,
        )
    except RaidenError as e:
        click.secho(f'FATAL: {e}', fg='red')
        sys.exit(1)

    return raiden_app
Exemple #41
0
def create_view_hash(acct, authroot_hash, randomizer) -> hex:
    acct_bytes = to_canonical_address(acct)
    authroot_hash_bytes = to_bytes(hexstr=authroot_hash)
    randomizer_bytes = to_bytes32(randomizer)
    return to_hex(keccak(acct_bytes+authroot_hash_bytes+randomizer_bytes))
Exemple #42
0
    def _run_smoketest():
        print_step('Starting Raiden')

        # invoke the raiden app
        app_ = ctx.invoke(app, **args)

        raiden_api = RaidenAPI(app_.raiden)
        rest_api = RestAPI(raiden_api)
        api_server = APIServer(rest_api)
        (api_host, api_port) = split_endpoint(args['api_address'])
        api_server.start(api_host, api_port)

        raiden_api.channel_open(
            contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
            to_canonical_address(token.contract.address),
            to_canonical_address(TEST_PARTNER_ADDRESS),
            None,
            None,
        )
        raiden_api.set_total_channel_deposit(
            contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
            to_canonical_address(token.contract.address),
            to_canonical_address(TEST_PARTNER_ADDRESS),
            TEST_DEPOSIT_AMOUNT,
        )

        smoketest_config['contracts'][
            'registry_address'] = to_checksum_address(
                contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], )
        smoketest_config['contracts'][
            'secret_registry_address'] = to_checksum_address(
                contract_addresses[CONTRACT_SECRET_REGISTRY], )
        smoketest_config['contracts'][
            'discovery_address'] = to_checksum_address(
                contract_addresses[CONTRACT_ENDPOINT_REGISTRY], )
        smoketest_config['contracts']['token_address'] = to_checksum_address(
            token.contract.address, )

        success = False
        try:
            print_step('Running smoketest')
            error = run_smoketests(app_.raiden, smoketest_config, debug=debug)
            if error is not None:
                append_report('Smoketest assertion error', error)
            else:
                success = True
        finally:
            app_.stop()
            ethereum.send_signal(2)

            err, out = ethereum.communicate()
            append_report('Ethereum init stdout',
                          ethereum_config['init_log_out'].decode('utf-8'))
            append_report('Ethereum init stderr',
                          ethereum_config['init_log_err'].decode('utf-8'))
            append_report('Ethereum stdout', out)
            append_report('Ethereum stderr', err)
            append_report('Smoketest configuration',
                          json.dumps(smoketest_config))
        if success:
            print_step(
                f'Smoketest successful, report was written to {report_file}')
        else:
            print_step(
                f'Smoketest had errors, report was written to {report_file}',
                error=True)
        return success
Exemple #43
0
def smoketest(ctx, debug, local_matrix, **kwargs):  # pylint: disable=unused-argument
    """ Test, that the raiden installation is sane. """
    import binascii
    from web3 import Web3, HTTPProvider
    from web3.middleware import geth_poa_middleware
    from raiden.api.python import RaidenAPI
    from raiden.tests.utils.geth import geth_wait_and_check
    from raiden.tests.integration.contracts.fixtures.contracts import deploy_token
    from raiden.tests.utils.smoketest import (
        TEST_PARTNER_ADDRESS,
        TEST_DEPOSIT_AMOUNT,
        deploy_smoketest_contracts,
        get_private_key,
        load_smoketest_config,
        start_ethereum,
        run_smoketests,
    )

    report_file = tempfile.mktemp(suffix='.log')
    configure_logging({'': 'DEBUG'}, log_file=report_file)

    def append_report(subject, data):
        with open(report_file, 'a', encoding='UTF-8') as handler:
            handler.write(f'{f" {subject.upper()} ":=^80}{os.linesep}')
            if data is not None:
                if isinstance(data, bytes):
                    data = data.decode()
                handler.writelines([data + os.linesep])

    append_report('Raiden version', json.dumps(get_system_spec()))
    append_report('Raiden log', None)

    step_count = 7
    if ctx.parent.params['transport'] == 'matrix':
        step_count = 8
    step = 0

    def print_step(description, error=False):
        nonlocal step
        step += 1
        click.echo(
            '{} {}'.format(
                click.style(f'[{step}/{step_count}]', fg='blue'),
                click.style(description, fg='green' if not error else 'red'),
            ), )

    print_step('Getting smoketest configuration')
    smoketest_config = load_smoketest_config()
    if not smoketest_config:
        append_report(
            'Smoketest configuration',
            'Could not load the smoketest genesis configuration file.',
        )

    print_step('Starting Ethereum node')
    ethereum, ethereum_config = start_ethereum(smoketest_config['genesis'])
    port = ethereum_config['rpc']
    web3_client = Web3(HTTPProvider(f'http://0.0.0.0:{port}'))
    web3_client.middleware_stack.inject(geth_poa_middleware, layer=0)
    random_marker = binascii.hexlify(b'raiden').decode()
    privatekeys = []
    geth_wait_and_check(web3_client, privatekeys, random_marker)

    print_step('Deploying Raiden contracts')
    host = '0.0.0.0'
    client = JSONRPCClient(
        host,
        ethereum_config['rpc'],
        get_private_key(),
        web3=web3_client,
    )
    contract_addresses = deploy_smoketest_contracts(client, 627)

    token_contract = deploy_token(client)
    token = token_contract(1000, 0, 'TKN', 'TKN')

    registry = TokenNetworkRegistry(
        client, contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY])

    registry.add_token(to_canonical_address(token.contract.address))

    print_step('Setting up Raiden')
    # setup cli arguments for starting raiden
    args = dict(
        discovery_contract_address=to_checksum_address(
            contract_addresses[CONTRACT_ENDPOINT_REGISTRY], ),
        registry_contract_address=to_checksum_address(
            contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], ),
        secret_registry_contract_address=to_checksum_address(
            contract_addresses[CONTRACT_SECRET_REGISTRY], ),
        eth_rpc_endpoint='http://127.0.0.1:{}'.format(port),
        keystore_path=ethereum_config['keystore'],
        address=ethereum_config['address'],
        network_id='627',
        transport=ctx.parent.params['transport'],
        matrix_server='http://localhost:8008'
        if ctx.parent.params['matrix_server'] == 'auto' else
        ctx.parent.params['matrix_server'],
    )
    smoketest_config['transport'] = args['transport']
    for option_ in app.params:
        if option_.name in args.keys():
            args[option_.name] = option_.process_value(ctx, args[option_.name])
        else:
            args[option_.name] = option_.default

    password_file = os.path.join(args['keystore_path'], 'password')
    with open(password_file, 'w') as handler:
        handler.write('password')

    port = next(get_free_port('127.0.0.1', 5001))
    args['password_file'] = click.File()(password_file)
    args['datadir'] = args['keystore_path']
    args['api_address'] = 'localhost:' + str(port)
    args['sync_check'] = False

    def _run_smoketest():
        print_step('Starting Raiden')

        # invoke the raiden app
        app_ = ctx.invoke(app, **args)

        raiden_api = RaidenAPI(app_.raiden)
        rest_api = RestAPI(raiden_api)
        api_server = APIServer(rest_api)
        (api_host, api_port) = split_endpoint(args['api_address'])
        api_server.start(api_host, api_port)

        raiden_api.channel_open(
            contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
            to_canonical_address(token.contract.address),
            to_canonical_address(TEST_PARTNER_ADDRESS),
            None,
            None,
        )
        raiden_api.set_total_channel_deposit(
            contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
            to_canonical_address(token.contract.address),
            to_canonical_address(TEST_PARTNER_ADDRESS),
            TEST_DEPOSIT_AMOUNT,
        )

        smoketest_config['contracts'][
            'registry_address'] = to_checksum_address(
                contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], )
        smoketest_config['contracts'][
            'secret_registry_address'] = to_checksum_address(
                contract_addresses[CONTRACT_SECRET_REGISTRY], )
        smoketest_config['contracts'][
            'discovery_address'] = to_checksum_address(
                contract_addresses[CONTRACT_ENDPOINT_REGISTRY], )
        smoketest_config['contracts']['token_address'] = to_checksum_address(
            token.contract.address, )

        success = False
        try:
            print_step('Running smoketest')
            error = run_smoketests(app_.raiden, smoketest_config, debug=debug)
            if error is not None:
                append_report('Smoketest assertion error', error)
            else:
                success = True
        finally:
            app_.stop()
            ethereum.send_signal(2)

            err, out = ethereum.communicate()
            append_report('Ethereum init stdout',
                          ethereum_config['init_log_out'].decode('utf-8'))
            append_report('Ethereum init stderr',
                          ethereum_config['init_log_err'].decode('utf-8'))
            append_report('Ethereum stdout', out)
            append_report('Ethereum stderr', err)
            append_report('Smoketest configuration',
                          json.dumps(smoketest_config))
        if success:
            print_step(
                f'Smoketest successful, report was written to {report_file}')
        else:
            print_step(
                f'Smoketest had errors, report was written to {report_file}',
                error=True)
        return success

    if args['transport'] == 'udp':
        with SocketFactory('127.0.0.1', port,
                           strategy='none') as mapped_socket:
            args['mapped_socket'] = mapped_socket
            success = _run_smoketest()
    elif args['transport'] == 'matrix' and local_matrix.lower() != 'none':
        args['mapped_socket'] = None
        print_step('Starting Matrix transport')
        try:
            with HTTPExecutor(
                    local_matrix,
                    status=r'^[24]\d\d$',
                    url=urljoin(args['matrix_server'],
                                '/_matrix/client/versions'),
                    shell=True,
            ):
                args['extra_config'] = {
                    'matrix': {
                        'discovery_room': {
                            'server': 'matrix.local.raiden'
                        },
                        'server_name': 'matrix.local.raiden',
                    },
                }
                success = _run_smoketest()
        except (PermissionError, ProcessExitedWithError):
            append_report('Matrix server start exception',
                          traceback.format_exc())
            print_step(
                f'Error during smoketest setup, report was written to {report_file}',
                error=True,
            )
            success = False
    elif args['transport'] == 'matrix' and local_matrix.lower() == "none":
        args['mapped_socket'] = None
        success = _run_smoketest()
    else:
        # Shouldn't happen
        raise RuntimeError(f"Invalid transport type '{args['transport']}'")

    if not success:
        sys.exit(1)
Exemple #44
0
 def from_dict(cls, data) -> 'ActionChangeNodeNetworkState':
     return cls(
         node_address=to_canonical_address(data['node_address']),
         network_state=data['network_state'],
     )
 def get_secret_registry_address(
         self, block_identifier: BlockIdentifier) -> SecretRegistryAddress:
     return SecretRegistryAddress(
         to_canonical_address(
             self.proxy.functions.secret_registry_address().call(
                 block_identifier=block_identifier)))
Exemple #46
0
def chain(chaindb, funded_address,
          funded_address_initial_balance):  # noqa: F811
    """
    Return a Chain object containing just the genesis block.

    The Chain's state includes one funded account, which can be found in the funded_address in the
    chain itself.

    This Chain will perform all validations when importing new blocks, so only valid and finalized
    blocks can be used with it. If you want to test importing arbitrarily constructe, not
    finalized blocks, use the chain_without_block_validation fixture instead.
    """
    genesis_params = {
        "bloom":
        0,
        "coinbase":
        to_canonical_address("8888f1f195afa192cfee860698584c030f4c9db1"),
        "difficulty":
        131072,
        "extra_data":
        b"B",
        "gas_limit":
        3141592,
        "gas_used":
        0,
        "mix_hash":
        decode_hex(
            "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
        ),  # noqa: E501
        "nonce":
        decode_hex("0102030405060708"),
        "block_number":
        0,
        "parent_hash":
        decode_hex(
            "0000000000000000000000000000000000000000000000000000000000000000"
        ),  # noqa: E501
        "receipt_root":
        decode_hex(
            "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
        ),  # noqa: E501
        "timestamp":
        1422494849,
        "transaction_root":
        decode_hex(
            "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
        ),  # noqa: E501
        "uncles_hash":
        decode_hex(
            "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
        )  # noqa: E501
    }
    genesis_state = {
        funded_address: {
            "balance": funded_address_initial_balance,
            "nonce": 0,
            "code": b"",
            "storage": {}
        }
    }
    klass = Chain.configure(__name__='TestChain',
                            vm_configuration=((constants.GENESIS_BLOCK_NUMBER,
                                               FrontierVM), ))
    chain = klass.from_genesis(chaindb, genesis_params, genesis_state)
    return chain
 def get_deprecation_executor(self,
                              block_identifier: BlockIdentifier) -> Address:
     return Address(
         to_canonical_address(
             self.proxy.functions.deprecation_executor().call(
                 block_identifier=block_identifier)))
from evm.vm.message import (
    Message, )
from evm.vm.computation import (
    BaseComputation, )
from evm.vm.transaction_context import (
    BaseTransactionContext, )

from eth_utils import (
    to_canonical_address, )

from evm.exceptions import (
    ValidationError, )

NORMALIZED_ADDRESS_A = "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
NORMALIZED_ADDRESS_B = "0xcd1722f3947def4cf144679da39c4c32bdc35681"
CANONICAL_ADDRESS_A = to_canonical_address(
    "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6")
CANONICAL_ADDRESS_B = to_canonical_address(
    "0xcd1722f3947def4cf144679da39c4c32bdc35681")


class DummyComputation(BaseComputation):
    def apply_message(self):
        pass

    def apply_create_message(self):
        pass


@pytest.fixture
def transaction_context():
    tx_context = BaseTransactionContext(
Exemple #49
0
def deploy_smoketest_contracts(
    client: JSONRPCClient,
    chain_id: ChainID,
    contract_manager: ContractManager,
    token_address: AddressHex,
) -> Dict[str, Address]:
    if client.eth_node is EthClient.GETH:
        client.web3.geth.personal.unlockAccount(client.web3.eth.accounts[0],
                                                DEFAULT_PASSPHRASE)
    elif client.eth_node is EthClient.PARITY:
        client.web3.parity.personal.unlockAccount(client.web3.eth.accounts[0],
                                                  DEFAULT_PASSPHRASE)

    contract_proxy, _ = client.deploy_single_contract(
        contract_name=CONTRACT_SECRET_REGISTRY,
        contract=contract_manager.get_contract(CONTRACT_SECRET_REGISTRY),
        constructor_parameters=None,
    )
    secret_registry_address = Address(
        to_canonical_address(contract_proxy.address))

    secret_registry_constructor_arguments = (
        to_checksum_address(secret_registry_address),
        chain_id,
        TEST_SETTLE_TIMEOUT_MIN,
        TEST_SETTLE_TIMEOUT_MAX,
        UINT256_MAX,
    )

    contract_proxy, _ = client.deploy_single_contract(
        contract_name=CONTRACT_TOKEN_NETWORK_REGISTRY,
        contract=contract_manager.get_contract(
            CONTRACT_TOKEN_NETWORK_REGISTRY),
        constructor_parameters=secret_registry_constructor_arguments,
    )
    token_network_registry_address = Address(
        to_canonical_address(contract_proxy.address))

    service_registry_constructor_arguments = (
        token_address,
        EMPTY_ADDRESS,
        int(500e18),
        6,
        5,
        180 * SECONDS_PER_DAY,
        1000,
        200 * SECONDS_PER_DAY,
    )
    service_registry_contract, _ = client.deploy_single_contract(
        contract_name=CONTRACT_SERVICE_REGISTRY,
        contract=contract_manager.get_contract(CONTRACT_SERVICE_REGISTRY),
        constructor_parameters=service_registry_constructor_arguments,
    )
    service_registry_address = Address(
        to_canonical_address(service_registry_contract.address))

    user_deposit_contract, _ = client.deploy_single_contract(
        contract_name=CONTRACT_USER_DEPOSIT,
        contract=contract_manager.get_contract(CONTRACT_USER_DEPOSIT),
        constructor_parameters=(token_address, UINT256_MAX),
    )
    user_deposit_address = Address(
        to_canonical_address(user_deposit_contract.address))

    monitoring_service_contract, _ = client.deploy_single_contract(
        contract_name=CONTRACT_MONITORING_SERVICE,
        contract=contract_manager.get_contract(CONTRACT_MONITORING_SERVICE),
        constructor_parameters=(
            token_address,
            service_registry_address,
            user_deposit_address,
            token_network_registry_address,
        ),
    )
    monitoring_service_address = Address(
        to_canonical_address(monitoring_service_contract.address))

    one_to_n_contract, _ = client.deploy_single_contract(
        contract_name=CONTRACT_ONE_TO_N,
        contract=contract_manager.get_contract(CONTRACT_ONE_TO_N),
        constructor_parameters=(user_deposit_address, chain_id,
                                service_registry_address),
    )
    one_to_n_address = Address(to_canonical_address(one_to_n_contract.address))

    proxy_manager = ProxyManager(
        rpc_client=client,
        contract_manager=contract_manager,
        metadata=ProxyManagerMetadata(
            token_network_registry_deployed_at=GENESIS_BLOCK_NUMBER,
            filters_start_at=GENESIS_BLOCK_NUMBER,
        ),
    )
    user_deposit_proxy = UserDeposit(
        jsonrpc_client=client,
        user_deposit_address=UserDepositAddress(
            to_canonical_address(user_deposit_contract.address)),
        contract_manager=contract_manager,
        proxy_manager=proxy_manager,
        block_identifier=BLOCK_ID_LATEST,
    )
    transaction_hash = user_deposit_proxy.init(
        monitoring_service_address=MonitoringServiceAddress(
            monitoring_service_address),
        one_to_n_address=OneToNAddress(one_to_n_address),
        given_block_identifier=BLOCK_ID_LATEST,
    )
    assert is_tx_hash_bytes(transaction_hash)

    addresses = {
        CONTRACT_SECRET_REGISTRY: secret_registry_address,
        CONTRACT_TOKEN_NETWORK_REGISTRY: token_network_registry_address,
        CONTRACT_SERVICE_REGISTRY: service_registry_address,
        CONTRACT_USER_DEPOSIT: user_deposit_address,
        CONTRACT_MONITORING_SERVICE: monitoring_service_address,
        CONTRACT_ONE_TO_N: one_to_n_address,
    }

    return addresses
Exemple #50
0
def token_proxy(deploy_client, token_contract):
    return Token(
        deploy_client,
        to_canonical_address(token_contract.contract.address),
    )
Exemple #51
0
def run_app(
    address,
    keystore_path,
    gas_price,
    eth_rpc_endpoint,
    tokennetwork_registry_contract_address,
    secret_registry_contract_address,
    endpoint_registry_contract_address,
    listen_address,
    mapped_socket,
    max_unresponsive_time,
    api_address,
    rpc,
    sync_check,
    console,
    password_file,
    web_ui,
    datadir,
    transport,
    matrix_server,
    network_id,
    environment_type,
    unrecoverable_error_should_crash,
    config=None,
    extra_config=None,
    **kwargs,
):
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements,unused-argument

    from raiden.app import App

    _assert_sql_version()

    if transport == 'udp' and not mapped_socket:
        raise RuntimeError('Missing socket')

    if datadir is None:
        datadir = os.path.join(os.path.expanduser('~'), '.raiden')

    address_hex = to_normalized_address(address) if address else None
    address_hex, privatekey_bin = prompt_account(address_hex, keystore_path,
                                                 password_file)
    address = to_canonical_address(address_hex)

    (listen_host, listen_port) = split_endpoint(listen_address)
    (api_host, api_port) = split_endpoint(api_address)

    config['transport']['udp']['host'] = listen_host
    config['transport']['udp']['port'] = listen_port
    config['console'] = console
    config['rpc'] = rpc
    config['web_ui'] = rpc and web_ui
    config['api_host'] = api_host
    config['api_port'] = api_port
    if mapped_socket:
        config['socket'] = mapped_socket.socket
        config['transport']['udp']['external_ip'] = mapped_socket.external_ip
        config['transport']['udp'][
            'external_port'] = mapped_socket.external_port
    config['transport_type'] = transport
    config['transport']['matrix']['server'] = matrix_server
    config['transport']['udp'][
        'nat_keepalive_retries'] = DEFAULT_NAT_KEEPALIVE_RETRIES
    timeout = max_unresponsive_time / DEFAULT_NAT_KEEPALIVE_RETRIES
    config['transport']['udp']['nat_keepalive_timeout'] = timeout
    config['privatekey_hex'] = encode_hex(privatekey_bin)
    config[
        'unrecoverable_error_should_crash'] = unrecoverable_error_should_crash

    parsed_eth_rpc_endpoint = urlparse(eth_rpc_endpoint)
    if not parsed_eth_rpc_endpoint.scheme:
        eth_rpc_endpoint = f'http://{eth_rpc_endpoint}'

    web3 = _setup_web3(eth_rpc_endpoint)

    rpc_client = JSONRPCClient(
        web3,
        privatekey_bin,
        gas_price_strategy=gas_price,
        block_num_confirmations=DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS,
        uses_infura='infura.io' in eth_rpc_endpoint,
    )

    blockchain_service = BlockChainService(
        privatekey_bin=privatekey_bin,
        jsonrpc_client=rpc_client,
        # Not giving the contract manager here, but injecting it later
        # since we first need blockchain service to calculate the network id
    )

    if network_id == 1:
        # temporarily until red eyes disallow raiden on the mainnet
        click.secho(
            'Running Raiden on the mainnet is currently not supported.',
            fg='red',
        )
        sys.exit(1)

    given_network_id = network_id
    node_network_id = blockchain_service.network_id
    known_given_network_id = given_network_id in ID_TO_NETWORKNAME
    known_node_network_id = node_network_id in ID_TO_NETWORKNAME

    if node_network_id != given_network_id:
        if known_given_network_id and known_node_network_id:
            click.secho(
                f"The chosen ethereum network '{ID_TO_NETWORKNAME[given_network_id]}' "
                f"differs from the ethereum client '{ID_TO_NETWORKNAME[node_network_id]}'. "
                "Please update your settings.",
                fg='red',
            )
        else:
            click.secho(
                f"The chosen ethereum network id '{given_network_id}' differs "
                f"from the ethereum client '{node_network_id}'. "
                "Please update your settings.",
                fg='red',
            )
        sys.exit(1)

    config['chain_id'] = given_network_id

    # interpret the provided string argument
    if environment_type == Environment.PRODUCTION:
        # Safe configuration: restrictions for mainnet apply and matrix rooms have to be private
        config['environment_type'] = Environment.PRODUCTION
        config['transport']['matrix']['private_rooms'] = True
    else:
        config['environment_type'] = Environment.DEVELOPMENT

    environment_type = config['environment_type']
    print(f'Raiden is running in {environment_type.value.lower()} mode')

    chain_config = {}
    contract_addresses_known = False
    contracts = dict()
    contracts_version = 'pre_limits' if environment_type == Environment.DEVELOPMENT else None
    config['contracts_path'] = contracts_precompiled_path(contracts_version)
    if node_network_id in ID_TO_NETWORKNAME and ID_TO_NETWORKNAME[
            node_network_id] != 'smoketest':
        deployment_data = get_contracts_deployed(node_network_id,
                                                 contracts_version)
        not_allowed = (  # for now we only disallow mainnet with test configuration
            network_id == 1 and environment_type == Environment.DEVELOPMENT)
        if not_allowed:
            click.secho(
                f'The chosen network ({ID_TO_NETWORKNAME[node_network_id]}) is not a testnet, '
                'but the "development" environment was selected.\n'
                'This is not allowed. Please start again with a safe environment setting '
                '(--environment production).',
                fg='red',
            )
            sys.exit(1)

        contracts = deployment_data['contracts']
        contract_addresses_known = True

    blockchain_service.inject_contract_manager(
        ContractManager(config['contracts_path']))

    if sync_check:
        check_synced(blockchain_service, known_node_network_id)

    contract_addresses_given = (
        tokennetwork_registry_contract_address is not None
        and secret_registry_contract_address is not None
        and endpoint_registry_contract_address is not None)

    if not contract_addresses_given and not contract_addresses_known:
        click.secho(
            f"There are no known contract addresses for network id '{given_network_id}'. "
            "Please provide them on the command line or in the configuration file.",
            fg='red',
        )
        sys.exit(1)

    try:
        token_network_registry = blockchain_service.token_network_registry(
            tokennetwork_registry_contract_address or to_canonical_address(
                contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['address'], ), )
    except ContractVersionMismatch as e:
        handle_contract_version_mismatch(e)
    except AddressWithoutCode:
        handle_contract_no_code('token network registry',
                                tokennetwork_registry_contract_address)
    except AddressWrongContract:
        handle_contract_wrong_address(
            'token network registry',
            tokennetwork_registry_contract_address,
        )

    try:
        secret_registry = blockchain_service.secret_registry(
            secret_registry_contract_address or to_canonical_address(
                contracts[CONTRACT_SECRET_REGISTRY]['address'], ), )
    except ContractVersionMismatch as e:
        handle_contract_version_mismatch(e)
    except AddressWithoutCode:
        handle_contract_no_code('secret registry',
                                secret_registry_contract_address)
    except AddressWrongContract:
        handle_contract_wrong_address('secret registry',
                                      secret_registry_contract_address)

    database_path = os.path.join(
        datadir,
        f'node_{pex(address)}',
        f'netid_{given_network_id}',
        f'network_{pex(token_network_registry.address)}',
        f'v{RAIDEN_DB_VERSION}_log.db',
    )
    config['database_path'] = database_path

    print(
        '\nYou are connected to the \'{}\' network and the DB path is: {}'.
        format(
            ID_TO_NETWORKNAME.get(given_network_id, given_network_id),
            database_path,
        ), )

    discovery = None
    if transport == 'udp':
        transport, discovery = _setup_udp(
            config,
            blockchain_service,
            address,
            contracts,
            endpoint_registry_contract_address,
        )
    elif transport == 'matrix':
        transport = _setup_matrix(config)
    else:
        raise RuntimeError(f'Unknown transport type "{transport}" given')

    raiden_event_handler = RaidenEventHandler()
    message_handler = MessageHandler()

    try:
        if 'contracts' in chain_config:
            start_block = chain_config['contracts']['TokenNetworkRegistry'][
                'block_number']
        else:
            start_block = 0

        raiden_app = App(
            config=config,
            chain=blockchain_service,
            query_start_block=start_block,
            default_registry=token_network_registry,
            default_secret_registry=secret_registry,
            transport=transport,
            raiden_event_handler=raiden_event_handler,
            message_handler=message_handler,
            discovery=discovery,
        )
    except RaidenError as e:
        click.secho(f'FATAL: {e}', fg='red')
        sys.exit(1)

    try:
        raiden_app.start()
    except RuntimeError as e:
        click.secho(f'FATAL: {e}', fg='red')
        sys.exit(1)
    except filelock.Timeout:
        name_or_id = ID_TO_NETWORKNAME.get(given_network_id, given_network_id)
        click.secho(
            f'FATAL: Another Raiden instance already running for account {address_hex} on '
            f'network id {name_or_id}',
            fg='red',
        )
        sys.exit(1)

    return raiden_app
                         }])
def test_cli_wrong_rpc_endpoint(cli_args, raiden_spawner):
    child = raiden_spawner(cli_args)

    expect_cli_until_acknowledgment(child)
    child.expect(".*Communicating with an external service failed.")


@pytest.mark.parametrize("changed_args", [{"network_id": "42"}])
def test_cli_wrong_network_id_try_kovan(cli_args, raiden_spawner):
    child = raiden_spawner(cli_args)
    expect_cli_until_acknowledgment(child)
    child.expect(
        "The configured network.*differs from the Ethereum client's network")


@pytest.mark.parametrize(
    "changed_args",
    [{
        "user_deposit_contract_address":
        to_checksum_address(
            to_canonical_address("0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359"))
    }],
)
def test_cli_registry_address_without_deployed_contract(
        cli_args, raiden_spawner):
    child = raiden_spawner(cli_args)

    expect_cli_until_acknowledgment(child)
    child.expect(".* does not contain code")
def test_token_network_proxy_update_transfer(
    token_network_proxy,
    private_keys,
    token_proxy,
    chain_id,
    web3,
    contract_manager,
):
    """Tests channel lifecycle, with `update_transfer` before settling"""
    token_network_address = to_canonical_address(
        token_network_proxy.proxy.contract.address)

    c1_client = JSONRPCClient(web3, private_keys[1])
    c1_chain = BlockChainService(private_keys[1], c1_client)
    c2_client = JSONRPCClient(web3, private_keys[2])
    c1_token_network_proxy = TokenNetwork(
        jsonrpc_client=c1_client,
        token_network_address=token_network_address,
        contract_manager=contract_manager,
    )
    c2_token_network_proxy = TokenNetwork(
        jsonrpc_client=c2_client,
        token_network_address=token_network_address,
        contract_manager=contract_manager,
    )
    # create a channel
    channel_identifier = c1_token_network_proxy.new_netting_channel(
        c2_client.address,
        10,
    )
    # deposit to the channel
    initial_balance = 100
    token_proxy.transfer(c1_client.address, initial_balance)
    token_proxy.transfer(c2_client.address, initial_balance)
    initial_balance_c1 = token_proxy.balance_of(c1_client.address)
    assert initial_balance_c1 == initial_balance
    initial_balance_c2 = token_proxy.balance_of(c2_client.address)
    assert initial_balance_c2 == initial_balance
    c1_token_network_proxy.set_total_deposit(
        channel_identifier,
        10,
        c2_client.address,
    )
    c2_token_network_proxy.set_total_deposit(
        channel_identifier,
        10,
        c1_client.address,
    )
    # balance proof signed by c1
    transferred_amount_c1 = 1
    transferred_amount_c2 = 3
    balance_proof_c1 = BalanceProof(
        channel_identifier=channel_identifier,
        token_network_address=to_checksum_address(token_network_address),
        nonce=1,
        chain_id=chain_id,
        transferred_amount=transferred_amount_c1,
    )
    balance_proof_c1.signature = encode_hex(
        eth_sign(
            privkey=encode_hex(private_keys[1]),
            data=balance_proof_c1.serialize_bin(),
        ))
    # balance proof signed by c2
    balance_proof_c2 = BalanceProof(
        channel_identifier=channel_identifier,
        token_network_address=to_checksum_address(token_network_address),
        nonce=2,
        chain_id=chain_id,
        transferred_amount=transferred_amount_c2,
    )
    balance_proof_c2.signature = encode_hex(
        eth_sign(
            privkey=encode_hex(private_keys[2]),
            data=balance_proof_c2.serialize_bin(),
        ))

    non_closing_data = balance_proof_c1.serialize_bin(
        msg_type=MessageTypeId.BALANCE_PROOF_UPDATE, ) + decode_hex(
            balance_proof_c1.signature)
    non_closing_signature = eth_sign(
        privkey=encode_hex(c2_client.privkey),
        data=non_closing_data,
    )

    with pytest.raises(RaidenUnrecoverableError) as exc:
        c2_token_network_proxy.update_transfer(
            channel_identifier,
            c1_client.address,
            decode_hex(balance_proof_c1.balance_hash),
            balance_proof_c1.nonce,
            decode_hex(balance_proof_c1.additional_hash),
            decode_hex(balance_proof_c1.signature),
            non_closing_signature,
        )

        assert 'not in a closed state' in str(exc)

    # close by c1
    c1_token_network_proxy.close(
        channel_identifier=channel_identifier,
        partner=c2_client.address,
        balance_hash=decode_hex(balance_proof_c2.balance_hash),
        nonce=balance_proof_c2.nonce,
        additional_hash=decode_hex(balance_proof_c2.additional_hash),
        signature=decode_hex(balance_proof_c2.signature),
    )

    # using invalid non-closing signature
    # Usual mistake when calling update Transfer - balance proof signature is missing in the data
    non_closing_data = balance_proof_c1.serialize_bin(
        msg_type=MessageTypeId.BALANCE_PROOF_UPDATE)
    non_closing_signature = eth_sign(
        privkey=encode_hex(c2_client.privkey),
        data=non_closing_data,
    )
    with pytest.raises(RaidenUnrecoverableError):
        c2_token_network_proxy.update_transfer(
            channel_identifier,
            c1_client.address,
            decode_hex(balance_proof_c1.balance_hash),
            balance_proof_c1.nonce,
            decode_hex(balance_proof_c1.additional_hash),
            decode_hex(balance_proof_c1.signature),
            non_closing_signature,
        )

    non_closing_data = balance_proof_c1.serialize_bin(
        msg_type=MessageTypeId.BALANCE_PROOF_UPDATE, ) + decode_hex(
            balance_proof_c1.signature)
    non_closing_signature = eth_sign(
        privkey=encode_hex(c2_client.privkey),
        data=non_closing_data,
    )
    c2_token_network_proxy.update_transfer(
        channel_identifier,
        c1_client.address,
        decode_hex(balance_proof_c1.balance_hash),
        balance_proof_c1.nonce,
        decode_hex(balance_proof_c1.additional_hash),
        decode_hex(balance_proof_c1.signature),
        non_closing_signature,
    )

    with pytest.raises(RaidenUnrecoverableError) as exc:
        c1_token_network_proxy.settle(
            channel_identifier=channel_identifier,
            transferred_amount=transferred_amount_c1,
            locked_amount=0,
            locksroot=EMPTY_HASH,
            partner=c2_client.address,
            partner_transferred_amount=transferred_amount_c2,
            partner_locked_amount=0,
            partner_locksroot=EMPTY_HASH,
        )

        assert 'cannot be settled before settlement window is over' in str(exc)

    wait_until_block(c1_chain, c1_chain.block_number() + 10)

    # settling with an invalid amount
    with pytest.raises(RaidenUnrecoverableError):
        c1_token_network_proxy.settle(
            channel_identifier=channel_identifier,
            transferred_amount=2,
            locked_amount=0,
            locksroot=EMPTY_HASH,
            partner=c2_client.address,
            partner_transferred_amount=2,
            partner_locked_amount=0,
            partner_locksroot=EMPTY_HASH,
        )

    # proper settle
    c1_token_network_proxy.settle(
        channel_identifier=channel_identifier,
        transferred_amount=transferred_amount_c1,
        locked_amount=0,
        locksroot=EMPTY_HASH,
        partner=c2_client.address,
        partner_transferred_amount=transferred_amount_c2,
        partner_locked_amount=0,
        partner_locksroot=EMPTY_HASH,
    )
    assert (token_proxy.balance_of(
        c2_client.address) == (initial_balance_c2 + transferred_amount_c1 -
                               transferred_amount_c2))
    assert (token_proxy.balance_of(
        c1_client.address) == (initial_balance_c1 + transferred_amount_c2 -
                               transferred_amount_c1))

    # Already settled
    with pytest.raises(RaidenUnrecoverableError) as exc:
        c2_token_network_proxy.set_total_deposit(
            channel_identifier,
            20,
            c1_client.address,
        )

        assert 'getChannelIdentifier returned 0' in str(exc)
Exemple #54
0
 def from_dict(cls, data):
     return cls(
         token_network_identifier=to_canonical_address(
             data['token_network_identifier']),
         channel_identifier=int(data['channel_identifier']),
     )
Exemple #55
0
CHECK_RDN_MIN_DEPOSIT_INTERVAL = 5 * 60
CHECK_GAS_RESERVE_INTERVAL = 5 * 60
CHECK_VERSION_INTERVAL = 3 * 60 * 60
CHECK_NETWORK_ID_INTERVAL = 5 * 60

DEFAULT_HTTP_REQUEST_TIMEOUT = 1.0  # seconds

DISCOVERY_DEFAULT_ROOM = "discovery"
MONITORING_BROADCASTING_ROOM = "monitoring"
PATH_FINDING_BROADCASTING_ROOM = "path_finding"

# According to the smart contracts as of 07/08:
# https://github.com/raiden-network/raiden-contracts/blob/fff8646ebcf2c812f40891c2825e12ed03cc7628/raiden_contracts/contracts/TokenNetwork.sol#L213
# channel_identifier can never be 0. We make this a requirement in the client and use this fact
# to signify that a channel_identifier of `0` passed to the messages adds them to the
# global queue
EMPTY_ADDRESS = b"\0" * 20

# Keep in sync with .circleci/config.yaml
HIGHEST_SUPPORTED_GETH_VERSION = "1.9.2"
LOWEST_SUPPORTED_GETH_VERSION = "1.8.21"
# this is the last stable version as of this comment
HIGHEST_SUPPORTED_PARITY_VERSION = "2.5.5"
LOWEST_SUPPORTED_PARITY_VERSION = "1.7.6"

WETH_TOKEN_ADDRESS = TokenAddress(
    to_canonical_address("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"))
DAI_TOKEN_ADDRESS = TokenAddress(
    to_canonical_address("0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359"))
Exemple #56
0
def token_network_proxy(deploy_client, token_network_contract):
    return TokenNetwork(
        deploy_client,
        to_canonical_address(token_network_contract.contract.address),
    )
Exemple #57
0
def normalize_to_address(value: AnyStr) -> Address:
    if value:
        return to_canonical_address(value)
    else:
        return CREATE_CONTRACT_ADDRESS
Exemple #58
0
 def from_dict(cls, data: typing.Dict[str,
                                      typing.Any]) -> 'ReceiveProcessed':
     return cls(
         sender=to_canonical_address(data['sender']),
         message_identifier=int(data['message_identifier']),
     )
Exemple #59
0
 def from_dict(cls, data) -> 'ReceiveProcessed':
     return cls(
         sender=to_canonical_address(data['sender']),
         message_identifier=data['message_identifier'],
     )
Exemple #60
0
def app(
    address,
    keystore_path,
    gas_price,
    eth_rpc_endpoint,
    registry_contract_address,
    secret_registry_contract_address,
    discovery_contract_address,
    listen_address,
    rpccorsdomain,
    mapped_socket,
    log_config,
    log_file,
    log_json,
    max_unresponsive_time,
    send_ping_time,
    api_address,
    rpc,
    sync_check,
    console,
    password_file,
    web_ui,
    datadir,
    nat,
    transport,
    matrix_server,
    network_id,
    extra_config=None,
):
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements,unused-argument

    from raiden.app import App
    from raiden.network.blockchain_service import BlockChainService

    if transport == 'udp' and not mapped_socket:
        raise RuntimeError('Missing socket')

    address_hex = to_normalized_address(address) if address else None
    address_hex, privatekey_bin = prompt_account(address_hex, keystore_path,
                                                 password_file)
    address = to_canonical_address(address_hex)

    (listen_host, listen_port) = split_endpoint(listen_address)
    (api_host, api_port) = split_endpoint(api_address)

    if datadir is None:
        datadir = os.path.join(os.path.expanduser('~'), '.raiden')

    config = deepcopy(App.DEFAULT_CONFIG)
    if extra_config:
        merge_dict(config, extra_config)

    config['host'] = listen_host
    config['port'] = listen_port
    config['console'] = console
    config['rpc'] = rpc
    config['web_ui'] = rpc and web_ui
    config['api_host'] = api_host
    config['api_port'] = api_port
    if mapped_socket:
        config['socket'] = mapped_socket.socket
        config['external_ip'] = mapped_socket.external_ip
        config['external_port'] = mapped_socket.external_port
    config['transport_type'] = transport
    config['matrix']['server'] = matrix_server
    config['transport'][
        'nat_keepalive_retries'] = DEFAULT_NAT_KEEPALIVE_RETRIES
    timeout = max_unresponsive_time / DEFAULT_NAT_KEEPALIVE_RETRIES
    config['transport']['nat_keepalive_timeout'] = timeout

    privatekey_hex = hexlify(privatekey_bin)
    config['privatekey_hex'] = privatekey_hex

    endpoint = eth_rpc_endpoint

    # Fallback to default port if only an IP address is given
    rpc_port = 8545
    if eth_rpc_endpoint.startswith('http://'):
        endpoint = eth_rpc_endpoint[len('http://'):]
        rpc_port = 80
    elif eth_rpc_endpoint.startswith('https://'):
        endpoint = eth_rpc_endpoint[len('https://'):]
        rpc_port = 443

    if ':' not in endpoint:  # no port was given in url
        rpc_host = endpoint
    else:
        rpc_host, rpc_port = split_endpoint(endpoint)

    rpc_client = JSONRPCClient(
        rpc_host,
        rpc_port,
        privatekey_bin,
        gas_price,
    )

    blockchain_service = BlockChainService(
        privatekey_bin,
        rpc_client,
        gas_price,
    )

    # this assumes the eth node is already online
    check_json_rpc(rpc_client)

    net_id = blockchain_service.network_id
    if net_id != network_id:
        if network_id in ID_TO_NETWORKNAME and net_id in ID_TO_NETWORKNAME:
            print((
                "The chosen ethereum network '{}' differs from the ethereum client '{}'. "
                'Please update your settings.').format(
                    ID_TO_NETWORKNAME[network_id], ID_TO_NETWORKNAME[net_id]))
        else:
            print((
                "The chosen ethereum network id '{}' differs from the ethereum client '{}'. "
                'Please update your settings.').format(network_id, net_id))
        sys.exit(1)

    if sync_check:
        check_synced(blockchain_service)

    database_path = os.path.join(datadir, 'netid_%s' % net_id, address_hex[:8],
                                 'log.db')
    config['database_path'] = database_path
    print(
        'You are connected to the \'{}\' network and the DB path is: {}'.
        format(
            ID_TO_NETWORKNAME.get(net_id) or net_id,
            database_path,
        ), )

    try:
        registry = blockchain_service.registry(registry_contract_address, )
    except ContractVersionMismatch:
        print(
            'Deployed registry contract version mismatch. '
            'Please update your Raiden installation.', )
        sys.exit(1)

    try:
        secret_registry = blockchain_service.secret_registry(
            secret_registry_contract_address, )
    except ContractVersionMismatch:
        print(
            'Deployed registry contract version mismatch. '
            'Please update your Raiden installation.', )
        sys.exit(1)

    discovery = None
    if transport == 'udp':
        check_discovery_registration_gas(blockchain_service, address)
        try:
            discovery = ContractDiscovery(
                blockchain_service.node_address,
                blockchain_service.discovery(discovery_contract_address),
            )
        except ContractVersionMismatch:
            print('Deployed discovery contract version mismatch. '
                  'Please update your Raiden installation.')
            sys.exit(1)
        throttle_policy = TokenBucket(
            config['transport']['throttle_capacity'],
            config['transport']['throttle_fill_rate'],
        )

        transport = UDPTransport(
            discovery,
            mapped_socket.socket,
            throttle_policy,
            config['transport'],
        )
    elif transport == 'matrix':
        transport = MatrixTransport(config['matrix'])
    else:
        raise RuntimeError(f'Unknown transport type "{transport}" given')

    raiden_app = App(
        config,
        blockchain_service,
        registry,
        secret_registry,
        transport,
        discovery,
    )

    return raiden_app