Ejemplo n.º 1
0
def test_save_and_load_channel(ms_database):
    token_network_address = get_random_address()
    ms_database.conn.execute("INSERT INTO token_network (address) VALUES (?)",
                             [token_network_address])
    for update_status in [
            None,
            OnChainUpdateStatus(
                update_sender_address=Address(get_random_address()),
                nonce=random.randint(0, UINT256_MAX),
            ),
    ]:
        channel = Channel(
            token_network_address=TokenNetworkAddress(token_network_address),
            identifier=ChannelID(random.randint(0, UINT256_MAX)),
            participant1=Address(get_random_address()),
            participant2=Address(get_random_address()),
            settle_timeout=random.randint(0, UINT256_MAX),
            state=random.choice(list(ChannelState)),
            closing_block=BlockNumber(random.randint(0, UINT256_MAX)),
            closing_participant=Address(get_random_address()),
            closing_tx_hash=TransactionHash('%d' %
                                            random.randint(0, UINT64_MAX)),
            claim_tx_hash=TransactionHash('%d' %
                                          random.randint(0, UINT64_MAX)),
            update_status=update_status,
        )
        ms_database.upsert_channel(channel)
        loaded_channel = ms_database.get_channel(
            token_network_address=channel.token_network_address,
            channel_id=channel.identifier)
        assert loaded_channel == channel
Ejemplo n.º 2
0
def populate_token_networks_random(
    token_networks: List[TokenNetwork],
    private_keys: List[str],
) -> None:
    # seed for pseudo-randomness from config constant, that changes from time to time
    random.seed(NUMBER_OF_CHANNELS)

    for token_network in token_networks:
        for channel_id_int in range(NUMBER_OF_CHANNELS):
            channel_id = ChannelIdentifier(channel_id_int)

            private_key1, private_key2 = random.sample(private_keys, 2)
            address1 = Address(private_key_to_address(private_key1))
            address2 = Address(private_key_to_address(private_key2))
            fee1 = random.randint(100, 10000)
            fee2 = random.randint(100, 10000)
            token_network.handle_channel_opened_event(channel_id, address1,
                                                      address2)

            # deposit to channels
            deposit1, deposit2 = random.sample(range(1000), 2)
            address1, address2 = token_network.channel_id_to_addresses[
                channel_id]
            token_network.handle_channel_new_deposit_event(
                channel_id, address1, deposit1)
            token_network.handle_channel_new_deposit_event(
                channel_id, address2, deposit2)
            # cuts negative values of probability distribution, fix with > 0 distribution

            token_network.update_fee(channel_id, address1, channel_id + 1,
                                     fee1)

            token_network.update_fee(channel_id, address2, channel_id + 1,
                                     fee2)
Ejemplo n.º 3
0
def populate_token_network_random(
    token_network_model: TokenNetwork,
    private_keys: List[str],
) -> None:
    # seed for pseudo-randomness from config constant, that changes from time to time
    random.seed(NUMBER_OF_CHANNELS)

    for channel_id_int in range(NUMBER_OF_CHANNELS):
        channel_id = ChannelIdentifier(channel_id_int)

        private_key1, private_key2 = random.sample(private_keys, 2)
        address1 = Address(private_key_to_address(private_key1))
        address2 = Address(private_key_to_address(private_key2))
        token_network_model.handle_channel_opened_event(
            channel_id,
            address1,
            address2,
        )

        # deposit to channels
        deposit1, deposit2 = random.sample(range(1000), 2)
        address1, address2 = token_network_model.channel_id_to_addresses[
            channel_id]
        token_network_model.handle_channel_new_deposit_event(
            channel_id,
            address1,
            deposit1,
        )
        token_network_model.handle_channel_new_deposit_event(
            channel_id,
            address2,
            deposit2,
        )
Ejemplo n.º 4
0
def pathfinding_service_full_mock(
    contracts_manager: ContractManager,
    token_network_model: TokenNetwork,
) -> Generator[PathfindingService, None, None]:
    with patch('pathfinding_service.service.BlockchainListener', new=Mock), \
            patch('pathfinding_service.service.MatrixListener', new=Mock):
        web3_mock = Mock()
        web3_mock.net.version = '1'
        web3_mock.eth.blockNumber = 1

        pathfinding_service = PathfindingService(
            web3=web3_mock,
            contract_manager=contracts_manager,
            registry_address=Address(
                '0xB9633dd9a9a71F22C933bF121d7a22008f66B908'),
            user_deposit_contract_address=Address('0x' + '1' * 20),
            private_key=
            '3a1076bf45ab87712ad64ccb3b10217737f7faacbf2872e88fdd9a537d8fe266',
            db_filename=':memory:',
        )
        pathfinding_service.token_networks = {
            token_network_model.address: token_network_model,
        }
        mock_udc = pathfinding_service.user_deposit_contract
        mock_udc.functions.effectiveBalance.return_value.call.return_value = 10000

        yield pathfinding_service
        pathfinding_service.stop()
Ejemplo n.º 5
0
def ms_database():
    return Database(
        filename=":memory:",
        chain_id=1,
        msc_address=Address("0x" + "2" * 40),
        registry_address=Address("0x" + "3" * 40),
        receiver=Address("0x" + "4" * 40),
    )
Ejemplo n.º 6
0
def ms_database():
    return Database(
        filename=':memory:',
        chain_id=1,
        msc_address=Address('0x' + '2' * 40),
        registry_address=Address('0x' + '3' * 40),
        receiver=Address('0x' + '4' * 40),
    )
Ejemplo n.º 7
0
def populate_token_network_random(token_network_model: TokenNetwork,
                                  private_keys: List[str]) -> None:
    # seed for pseudo-randomness from config constant, that changes from time to time
    random.seed(NUMBER_OF_CHANNELS)

    for channel_id_int in range(NUMBER_OF_CHANNELS):
        channel_id = ChannelID(channel_id_int)

        private_key1, private_key2 = random.sample(private_keys, 2)
        address1 = Address(private_key_to_address(private_key1))
        address2 = Address(private_key_to_address(private_key2))
        settle_timeout = 15
        token_network_model.handle_channel_opened_event(
            channel_id, address1, address2, settle_timeout)

        # deposit to channels
        deposit1 = TokenAmount(random.randint(0, 1000))
        deposit2 = TokenAmount(random.randint(0, 1000))
        address1, address2 = token_network_model.channel_id_to_addresses[
            channel_id]
        token_network_model.handle_channel_new_deposit_event(
            channel_id, address1, deposit1)
        token_network_model.handle_channel_new_deposit_event(
            channel_id, address2, deposit2)
        token_network_model.handle_channel_balance_update_message(
            UpdatePFS(
                canonical_identifier=CanonicalIdentifier(
                    chain_identifier=ChainID(1),
                    channel_identifier=channel_id,
                    token_network_address=TokenNetworkAddressBytes(
                        decode_hex(token_network_model.address)),
                ),
                updating_participant=decode_hex(address1),
                other_participant=decode_hex(address2),
                updating_nonce=Nonce(1),
                other_nonce=Nonce(1),
                updating_capacity=deposit1,
                other_capacity=deposit2,
                reveal_timeout=2,
                mediation_fee=FeeAmount(0),
            ))
        token_network_model.handle_channel_balance_update_message(
            UpdatePFS(
                canonical_identifier=CanonicalIdentifier(
                    chain_identifier=ChainID(1),
                    channel_identifier=channel_id,
                    token_network_address=TokenNetworkAddressBytes(
                        decode_hex(token_network_model.address)),
                ),
                updating_participant=decode_hex(address2),
                other_participant=decode_hex(address1),
                updating_nonce=Nonce(2),
                other_nonce=Nonce(1),
                updating_capacity=deposit2,
                other_capacity=deposit1,
                reveal_timeout=2,
                mediation_fee=FeeAmount(0),
            ))
Ejemplo n.º 8
0
def test_balance_proof():
    # test balance proof with computed balance hash
    balance_proof = BalanceProof(
        channel_identifier=ChannelIdentifier(
            '0x3131313131313131313131313131313131313131313131313131313131313131',
        ),
        token_network_address=Address(
            '0x82dd0e0eA3E84D00Cc119c46Ee22060939E5D1FC'),
        nonce=1,
        chain_id=321,
        transferred_amount=5,
        locksroot='0x%064x' % 5,
        additional_hash='0x%064x' % 0,
    )
    serialized = balance_proof.serialize_data()

    assert serialized['channel_identifier'] == balance_proof.channel_identifier
    assert is_same_address(
        serialized['token_network_address'],
        balance_proof.token_network_address,
    )
    assert serialized['nonce'] == balance_proof.nonce
    assert serialized['chain_id'] == balance_proof.chain_id
    assert serialized['additional_hash'] == balance_proof.additional_hash
    assert serialized['balance_hash'] == balance_proof.balance_hash

    assert serialized['locksroot'] == balance_proof.locksroot
    assert serialized['transferred_amount'] == balance_proof.transferred_amount
    assert serialized['locked_amount'] == balance_proof.locked_amount

    # test balance proof with balance hash set from constructor
    balance_proof = BalanceProof(
        channel_identifier=ChannelIdentifier(
            '0x3131313131313131313131313131313131313131313131313131313131313131',
        ),
        token_network_address=Address(
            '0x82dd0e0eA3E84D00Cc119c46Ee22060939E5D1FC'),
        nonce=1,
        chain_id=321,
        balance_hash='0x%064x' % 5,
        locked_amount=0,
        additional_hash='0x%064x' % 0,
    )
    serialized = balance_proof.serialize_data()

    with pytest.raises(KeyError):
        serialized['transferred_amount']

    assert serialized['channel_identifier'] == balance_proof.channel_identifier
    assert is_same_address(
        serialized['token_network_address'],
        balance_proof.token_network_address,
    )
    assert serialized['nonce'] == balance_proof.nonce
    assert serialized['chain_id'] == balance_proof.chain_id
    assert serialized['additional_hash'] == balance_proof.additional_hash
    assert serialized['balance_hash'] == balance_proof.balance_hash
Ejemplo n.º 9
0
def populate_token_network_random(
    token_network_model: TokenNetwork,
    private_keys: List[str],
) -> None:
    # seed for pseudo-randomness from config constant, that changes from time to time
    random.seed(NUMBER_OF_CHANNELS)

    for channel_id_int in range(NUMBER_OF_CHANNELS):
        channel_id = ChannelIdentifier(channel_id_int)

        private_key1, private_key2 = random.sample(private_keys, 2)
        address1 = Address(private_key_to_address(private_key1))
        address2 = Address(private_key_to_address(private_key2))
        settle_timeout = 15
        token_network_model.handle_channel_opened_event(
            channel_id,
            address1,
            address2,
            settle_timeout,
        )

        # deposit to channels
        deposit1, deposit2 = random.sample(range(1000), 2)
        address1, address2 = token_network_model.channel_id_to_addresses[
            channel_id]
        token_network_model.handle_channel_new_deposit_event(
            channel_id,
            address1,
            deposit1,
        )
        token_network_model.handle_channel_new_deposit_event(
            channel_id,
            address2,
            deposit2,
        )
        token_network_model.handle_channel_balance_update_message(
            channel_identifier=channel_id,
            updating_participant=address1,
            other_participant=address2,
            updating_nonce=1,
            other_nonce=1,
            updating_capacity=deposit1,
            other_capacity=deposit2,
            reveal_timeout=2,
        )
        token_network_model.handle_channel_balance_update_message(
            channel_identifier=channel_id,
            updating_participant=address2,
            other_participant=address1,
            updating_nonce=2,
            other_nonce=1,
            updating_capacity=deposit1,
            other_capacity=deposit2,
            reveal_timeout=2,
        )
Ejemplo n.º 10
0
def test_monitor_new_balance_proof_event_handler_sets_update_status(context: Context,):
    context = setup_state_with_closed_channel(context)

    new_balance_event = ReceiveMonitoringNewBalanceProofEvent(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        channel_identifier=DEFAULT_CHANNEL_IDENTIFIER,
        reward_amount=TokenAmount(1),
        nonce=Nonce(2),
        ms_address=Address("C"),
        raiden_node_address=DEFAULT_PARTICIPANT2,
        block_number=BlockNumber(23),
    )

    channel = context.db.get_channel(
        new_balance_event.token_network_address, new_balance_event.channel_identifier
    )
    assert channel
    assert channel.update_status is None

    monitor_new_balance_proof_event_handler(new_balance_event, context)

    assert context.db.channel_count() == 1
    channel = context.db.get_channel(
        new_balance_event.token_network_address, new_balance_event.channel_identifier
    )
    assert channel
    assert channel.update_status is not None
    assert channel.update_status.nonce == 2
    assert channel.update_status.update_sender_address == "C"

    new_balance_event2 = ReceiveMonitoringNewBalanceProofEvent(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        channel_identifier=DEFAULT_CHANNEL_IDENTIFIER,
        reward_amount=TokenAmount(1),
        nonce=Nonce(5),
        ms_address=Address("D"),
        raiden_node_address=DEFAULT_PARTICIPANT2,
        block_number=BlockNumber(23),
    )

    monitor_new_balance_proof_event_handler(new_balance_event2, context)

    assert context.db.channel_count() == 1
    channel = context.db.get_channel(
        new_balance_event.token_network_address, new_balance_event.channel_identifier
    )
    assert channel
    assert channel.update_status is not None
    assert channel.update_status.nonce == 5
    assert channel.update_status.update_sender_address == "D"
Ejemplo n.º 11
0
def test_balance_proof():
    balance_proof = BalanceProof(
        channel_identifier=ChannelIdentifier(123),
        token_network_address=Address('0x82dd0e0eA3E84D00Cc119c46Ee22060939E5D1FC'),
        nonce=1,
        chain_id=321,
        balance_hash='0x%064x' % 5,
        transferred_amount=1,
        locked_amount=0,
        additional_hash='0x%064x' % 0,
    )
    serialized = balance_proof.serialize_data()

    assert serialized['channel_identifier'] == balance_proof.channel_identifier
    assert is_same_address(
        serialized['token_network_address'],
        balance_proof.token_network_address
    )
    assert serialized['nonce'] == balance_proof.nonce
    assert serialized['chain_id'] == balance_proof.chain_id
    assert serialized['additional_hash'] == balance_proof.additional_hash
    assert serialized['balance_hash'] == balance_proof.balance_hash

    with pytest.raises(KeyError):
        serialized['transferred_amount']

    balance_proof = BalanceProof(
        channel_identifier=ChannelIdentifier(123),
        token_network_address=Address('0x82dd0e0eA3E84D00Cc119c46Ee22060939E5D1FC'),
        nonce=1,
        chain_id=321,
        locksroot='0x%064x' % 5,
        transferred_amount=1,
        locked_amount=0,
        additional_hash='0x%064x' % 0,
    )
    serialized = balance_proof.serialize_data()

    assert serialized['channel_identifier'] == balance_proof.channel_identifier
    assert is_same_address(
        serialized['token_network_address'],
        balance_proof.token_network_address
    )
    assert serialized['nonce'] == balance_proof.nonce
    assert serialized['chain_id'] == balance_proof.chain_id
    assert serialized['additional_hash'] == balance_proof.additional_hash

    assert serialized['locksroot'] == balance_proof.locksroot
    assert serialized['transferred_amount'] == balance_proof.transferred_amount
    assert serialized['locked_amount'] == balance_proof.locked_amount
Ejemplo n.º 12
0
 def __set__(self, obj, value):
     if not isinstance(value, str):
         raise ValueError("%s requires a string" % (self.__class__.__name__))
     if not is_checksum_address(value):
         raise ValueError("%s requires a checksummed ethereum address" %
                          (self.__class__.__name__))
     setattr(obj, self.private_attribute_name, Address(value))
Ejemplo n.º 13
0
def test_action_claim_reward_triggered_event_handler_without_update_state_doesnt_trigger_claim_call(  # noqa
        context: Context, ):
    """ Tests that `claimReward` is called when the ActionMonitoringTriggeredEvent is triggered and
    user has sufficient balance in user deposit contract
    """
    context = setup_state_with_closed_channel(context)

    context.db.upsert_monitor_request(
        get_signed_monitor_request(nonce=Nonce(6),
                                   reward_amount=TokenAmount(0)))

    trigger_event = ActionClaimRewardTriggeredEvent(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        channel_identifier=DEFAULT_CHANNEL_IDENTIFIER,
        non_closing_participant=DEFAULT_PARTICIPANT2,
    )

    channel = context.db.get_channel(trigger_event.token_network_address,
                                     trigger_event.channel_identifier)
    assert channel
    assert channel.claim_tx_hash is None

    # Set update state
    channel.update_status = OnChainUpdateStatus(
        update_sender_address=Address('0x' + '1' * 40), nonce=Nonce(6))
    context.db.upsert_channel(channel)

    action_claim_reward_triggered_event_handler(trigger_event, context)

    # check that the monitor call has been done
    assert context.monitoring_service_contract.functions.claimReward.called is False
Ejemplo n.º 14
0
    def _setup(
        self,
        chain_id: int,
        receiver: str,
        sync_start_block: BlockNumber,
        **contract_addresses: Address,
    ) -> None:
        """ Make sure that the db is initialized an matches the given settings """
        assert chain_id >= 0
        assert is_checksum_address(receiver)
        for contract, address in contract_addresses.items():
            assert is_checksum_address(address), f"Bad {contract}: {address}!"

        initialized = self.conn.execute(
            "SELECT name FROM sqlite_master WHERE type='table' AND name='blockchain'"
        ).fetchone()
        settings = dict(chain_id=chain_id,
                        receiver=receiver,
                        **contract_addresses)

        if initialized:
            self._check_settings(settings, contract_addresses)
        else:
            # create db schema
            with open(self.schema_filename) as schema_file:
                self.conn.executescript(schema_file.read())
            update_stmt = "UPDATE blockchain SET {}".format(",".join(
                f"{key} = :{key}"
                for key in ["chain_id", "receiver", "latest_known_block"] +
                list(contract_addresses)))
            self.conn.execute(
                update_stmt,
                dict(latest_known_block=sync_start_block, **settings))
Ejemplo n.º 15
0
def check_supplied_token_network_addresses(token_network_addresses: List[str],
                                           web3: Web3) -> List[Address]:
    result = []
    for address in token_network_addresses:
        if not is_checksum_address(address):
            log.error(
                f"Token Network address '{address}' is not a checksum address. Ignoring."
            )
            continue

        if not is_code_at_address(Address(address), web3):
            log.error(f"Token network at '{address}' has no code. Ignoring.")
            continue

        result.append(Address(address))

    return result
Ejemplo n.º 16
0
def test_scheduled_events(ms_database):
    # Add token network used as foreign key
    ms_database.conn.execute("INSERT INTO token_network(address) VALUES (?)", ['a'])

    event1 = ScheduledEvent(
        trigger_block_number=BlockNumber(23),
        event=ActionMonitoringTriggeredEvent(
            token_network_address=TokenNetworkAddress('a'),
            channel_identifier=ChannelID(1),
            non_closing_participant=Address('b'),
        ),
    )

    assert ms_database.scheduled_event_count() == 0
    ms_database.upsert_scheduled_event(event=event1)
    assert ms_database.scheduled_event_count() == 1

    event2 = ScheduledEvent(
        trigger_block_number=BlockNumber(24),
        event=ActionMonitoringTriggeredEvent(
            token_network_address=TokenNetworkAddress('a'),
            channel_identifier=ChannelID(1),
            non_closing_participant=Address('b'),
        ),
    )

    ms_database.upsert_scheduled_event(event=event2)
    assert ms_database.scheduled_event_count() == 2

    assert len(ms_database.get_scheduled_events(22)) == 0
    assert len(ms_database.get_scheduled_events(23)) == 1
    assert len(ms_database.get_scheduled_events(24)) == 2

    ms_database.upsert_scheduled_event(event=event1)
    assert ms_database.scheduled_event_count() == 2

    assert len(ms_database.get_scheduled_events(22)) == 0
    assert len(ms_database.get_scheduled_events(23)) == 1
    assert len(ms_database.get_scheduled_events(24)) == 2

    ms_database.remove_scheduled_event(event2)
    assert len(ms_database.get_scheduled_events(22)) == 0
    assert len(ms_database.get_scheduled_events(23)) == 1
    assert len(ms_database.get_scheduled_events(24)) == 1
Ejemplo n.º 17
0
    def __init__(
        self,
        web3: Web3,
        contracts: Dict[str, Contract],
        private_key: str,
        db_filename: str,
        sync_start_block: BlockNumber = BlockNumber(0),
        required_confirmations: int = 8,
        poll_interval: float = 10,
        service_fee: int = 0,
    ):
        super().__init__()

        self.web3 = web3
        self.registry_address = contracts[CONTRACT_TOKEN_NETWORK_REGISTRY].address
        self.sync_start_block = sync_start_block
        self.required_confirmations = required_confirmations
        self.poll_interval = poll_interval
        self.chain_id = ChainID(int(web3.net.version))
        self.private_key = private_key
        self.address = private_key_to_address(private_key)
        self.service_fee = service_fee

        self.is_running = gevent.event.Event()
        self.token_networks: Dict[TokenNetworkAddress, TokenNetwork] = {}
        self.database = PFSDatabase(filename=db_filename, pfs_address=self.address)
        self.user_deposit_contract = contracts[CONTRACT_USER_DEPOSIT]

        self.last_known_block = 0
        self.blockchain_state = BlockchainState(
            chain_id=self.chain_id,
            token_network_registry_address=self.registry_address,
            monitor_contract_address=Address(''),  # FIXME
            latest_known_block=self.sync_start_block,
            token_network_addresses=[],
        )
        log.info(
            'Listening to token network registry',
            registry_address=self.registry_address,
            start_block=sync_start_block,
        )

        try:
            self.matrix_listener = MatrixListener(
                private_key=private_key,
                chain_id=self.chain_id,
                callback=self.handle_message,
                service_room_suffix=PATH_FINDING_BROADCASTING_ROOM,
            )
        except ConnectionError as e:
            log.critical('Could not connect to broadcasting system.', exc=e)
            sys.exit(1)
Ejemplo n.º 18
0
    def post(self, token_network_address: str):
        token_network_error = self._validate_token_network_argument(
            token_network_address)
        if token_network_error is not None:
            return token_network_error

        parser = reqparse.RequestParser()
        parser.add_argument('from',
                            type=str,
                            help='Payment initiator address.')
        parser.add_argument('to', type=str, help='Payment target address.')
        parser.add_argument('value', type=int, help='Maximum payment value.')
        parser.add_argument(
            'max_paths',
            type=int,
            help='Number of paths requested.',
            default=DEFAULT_MAX_PATHS,
        )

        args = parser.parse_args()
        error = self._validate_args(args)
        if error is not None:
            return error

        json = request.get_json()
        if not json:
            raise exceptions.ApiException('JSON payload expected')
        process_payment(json.get('iou'), self.pathfinding_service)

        token_network = self.pathfinding_service.token_networks.get(
            Address(token_network_address), )
        # Existence is checked in _validate_token_network_argument
        assert token_network, 'Requested token network cannot be found'

        try:
            paths = token_network.get_paths(
                source=args['from'],
                target=args['to'],
                value=args.value,
                max_paths=args.max_paths,
            )
        except NetworkXNoPath:
            return {
                'errors':
                'No suitable path found for transfer from {} to {}.'.format(
                    args['from'],
                    args['to'],
                )
            }, 400

        return {'result': paths}, 200
Ejemplo n.º 19
0
def test_contract_info_overwrite_defaults():
    address1 = Address("0x" + "1" * 40)
    address2 = Address("0x" + "2" * 40)
    address3 = Address("0x" + "3" * 40)
    infos, start_block = get_contract_addresses_and_start_block(
        chain_id=DEFAULT_CHAIN_ID,
        contracts_version=DEFAULT_VERSION,
        contracts=[
            CONTRACT_TOKEN_NETWORK_REGISTRY,
            CONTRACT_MONITORING_SERVICE,
            CONTRACT_USER_DEPOSIT,
        ],
        address_overwrites={
            CONTRACT_TOKEN_NETWORK_REGISTRY: address1,
            CONTRACT_MONITORING_SERVICE: address2,
            CONTRACT_USER_DEPOSIT: address3,
        },
    )
    assert infos is not None
    assert infos[CONTRACT_TOKEN_NETWORK_REGISTRY] == address1
    assert infos[CONTRACT_MONITORING_SERVICE] == address2
    assert infos[CONTRACT_USER_DEPOSIT] == address3
    assert start_block == 0
Ejemplo n.º 20
0
def test_save_and_load_token_networks(pathfinding_service_mock_empty):
    pfs = pathfinding_service_mock_empty

    token_address = Address("0x" + "1" * 40)
    token_network_address = TokenNetworkAddress("0x" + "2" * 40)
    channel_id = ChannelID(1)
    p1 = Address("0x" + "3" * 40)
    p2 = Address("0x" + "4" * 40)
    events = [
        ReceiveTokenNetworkCreatedEvent(
            token_address=token_address,
            token_network_address=token_network_address,
            block_number=BlockNumber(1),
        ),
        ReceiveChannelOpenedEvent(
            token_network_address=token_network_address,
            channel_identifier=channel_id,
            participant1=p1,
            participant2=p2,
            settle_timeout=2**
            65,  # larger than max_uint64 to check hex storage
            block_number=BlockNumber(2),
        ),
    ]
    for event in events:
        pfs.handle_event(event)
    assert len(pfs.token_networks) == 1

    loaded_networks = pfs._load_token_networks()  # pylint: disable=protected-access
    assert len(loaded_networks) == 1

    orig = list(pfs.token_networks.values())[0]
    loaded = list(loaded_networks.values())[0]
    assert loaded.address == orig.address
    assert loaded.channel_id_to_addresses == orig.channel_id_to_addresses
    assert loaded.G.nodes == orig.G.nodes
Ejemplo n.º 21
0
def test_save_and_load_token_networks(pathfinding_service_mock):
    pfs = pathfinding_service_mock
    pfs.token_networks = {}  # the mock does not fit this case exactly

    token_address = Address("0x" + "1" * 40)
    token_network_address = TokenNetworkAddress("0x" + "2" * 40)
    channel_id = ChannelID(1)
    p1 = Address("0x" + "3" * 40)
    p2 = Address("0x" + "4" * 40)
    events = [
        ReceiveTokenNetworkCreatedEvent(
            token_address=token_address,
            token_network_address=token_network_address,
            block_number=BlockNumber(1),
        ),
        ReceiveChannelOpenedEvent(
            token_network_address=token_network_address,
            channel_identifier=channel_id,
            participant1=p1,
            participant2=p2,
            settle_timeout=1000,
            block_number=BlockNumber(2),
        ),
    ]
    for event in events:
        pfs.handle_event(event)
    assert len(pfs.token_networks) == 1

    loaded_networks = pfs._load_token_networks()
    assert len(loaded_networks) == 1

    orig = list(pfs.token_networks.values())[0]
    loaded = list(loaded_networks.values())[0]
    assert loaded.address == orig.address
    assert loaded.channel_id_to_addresses == orig.channel_id_to_addresses
    assert loaded.G.nodes == orig.G.nodes
Ejemplo n.º 22
0
def test_monitor_reward_claimed_event_handler(context: Context, log):
    context = setup_state_with_closed_channel(context)

    claim_event = ReceiveMonitoringRewardClaimedEvent(
        ms_address=context.ms_state.address,
        amount=TokenAmount(1),
        reward_identifier="REWARD",
        block_number=BlockNumber(23),
    )

    monitor_reward_claim_event_handler(claim_event, context)
    assert log.has("Successfully claimed reward")

    claim_event.ms_address = Address("C")
    monitor_reward_claim_event_handler(claim_event, context)
    assert log.has("Another MS claimed reward")
Ejemplo n.º 23
0
 def _process_new_blocks(self, last_block: BlockNumber) -> None:
     _, events = get_blockchain_events(
         web3=self.web3,
         contract_manager=CONTRACT_MANAGER,
         chain_state=BlockchainState(
             latest_known_block=self.database.get_latest_known_block(),
             token_network_addresses=list(self.token_networks.keys()),
             token_network_registry_address=self.registry_address,
             monitor_contract_address=Address(""),  # FIXME
             chain_id=self.chain_id,
         ),
         to_block=last_block,
         query_ms=False,
     )
     for event in events:
         self.handle_event(event)
Ejemplo n.º 24
0
def get_contract_addresses_and_start_block(
    chain_id: ChainID,
    contracts: List[str],
    address_overwrites: Dict[str, Address],
    contracts_version: str = None,
) -> Tuple[Dict[str, Address], BlockNumber]:
    """ Returns contract addresses and start query block for a given chain and contracts version.

    The default contracts can be overwritten by the additional parameters.

    Args:
        chain_id: The chain id to look for deployed contracts.
        contracts: The list of contracts which should be considered
        address_overwrites: Dict of addresses which should be used instead of
            the ones in the requested deployment.
        contracts_version: The version of the contracts to use.

    Returns: A dictionary with the contract addresses and start block for the given information
    """
    try:
        contract_data = get_contracts_deployment_info(
            chain_id=chain_id, version=contracts_version)
    except ValueError:
        log.error(
            'No deployed contracts were found at the default registry',
            contracts_version=contracts_version,
        )
        sys.exit(1)

    # Get deployed addresses for those contracts which have no overwrites
    addresses = {
        c: address_overwrites.get(
            c, Address(contract_data['contracts'][c]['address']))
        for c in contracts
    }

    # Set start block to zero if any contract addresses are overwritten
    if any(address_overwrites.values()):
        start_block = BlockNumber(0)
    else:
        start_block = BlockNumber(
            max(
                0,
                min(contract_data['contracts'][c]['block_number']
                    for c in contracts)))

    return addresses, start_block
Ejemplo n.º 25
0
    def on_fee_info_message(self, fee_info: FeeInfo):
        try:
            self._check_chain_id(fee_info.chain_id)
        except ValueError as error:
            log.error('FeeInfo chain_id does not match: %s', str(error))
            return

        token_network = self._get_token_network(fee_info.token_network_address)

        if token_network is None:
            return

        log.debug('Received FeeInfo message for token network {}'.format(
            token_network.address))

        token_network.update_fee(fee_info.channel_identifier,
                                 Address(to_checksum_address(fee_info.signer)),
                                 fee_info.nonce, fee_info.relative_fee)
Ejemplo n.º 26
0
def pathfinding_service_mocked_listeners(
    contracts_manager: ContractManager,
    web3: Web3,
    user_deposit_contract: Contract,
) -> Generator[PathfindingService, None, None]:
    """ Returns a PathfindingService with mocked blockchain listeners. """
    with patch('pathfinding_service.service.BlockchainListener', new=BlockchainListenerMock), \
            patch('pathfinding_service.service.MatrixListener', new=Mock):
        pathfinding_service = PathfindingService(
            web3=web3,
            contract_manager=contracts_manager,
            registry_address=Address(''),
            user_deposit_contract_address=user_deposit_contract.address,
            private_key=
            '3a1076bf45ab87712ad64ccb3b10217737f7faacbf2872e88fdd9a537d8fe266',
            db_filename=':memory:',
        )

        yield pathfinding_service
Ejemplo n.º 27
0
def test_action_monitoring_triggered_event_handler_does_not_trigger_monitor_call_when_nonce_to_small(  # noqa
        context: Context, ):
    context = setup_state_with_closed_channel(context)

    event3 = ReceiveMonitoringNewBalanceProofEvent(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        channel_identifier=DEFAULT_CHANNEL_IDENTIFIER,
        reward_amount=TokenAmount(1),
        nonce=Nonce(5),
        ms_address=Address('C'),
        raiden_node_address=DEFAULT_PARTICIPANT2,
        block_number=BlockNumber(23),
    )

    channel = context.db.get_channel(event3.token_network_address,
                                     event3.channel_identifier)
    assert channel
    assert channel.update_status is None

    monitor_new_balance_proof_event_handler(event3, context)

    # add MR to DB, with nonce being smaller than in event3
    context.db.upsert_monitor_request(
        get_signed_monitor_request(nonce=Nonce(4)))

    event4 = ActionMonitoringTriggeredEvent(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        channel_identifier=DEFAULT_CHANNEL_IDENTIFIER,
        non_closing_participant=DEFAULT_PARTICIPANT2,
    )

    channel = context.db.get_channel(event4.token_network_address,
                                     event4.channel_identifier)
    assert channel
    assert channel.update_status is not None
    assert channel.closing_tx_hash is None

    action_monitoring_triggered_event_handler(event4, context)

    assert context.db.channel_count() == 1
    assert channel
    assert channel.closing_tx_hash is None
Ejemplo n.º 28
0
    def get(self, token_network_address: str):
        token_network_error = self._validate_token_network_argument(
            token_network_address)
        if token_network_error is not None:
            return token_network_error

        parser = reqparse.RequestParser()
        parser.add_argument('from',
                            type=str,
                            help='Payment initiator address.')
        parser.add_argument('to', type=str, help='Payment target address.')
        parser.add_argument('value', type=int, help='Maximum payment value.')
        parser.add_argument('num_paths',
                            type=int,
                            help='Number of paths requested.')

        args = parser.parse_args()
        error = self._validate_args(args)
        if error is not None:
            return error

        token_network = self.pathfinding_service.token_networks.get(
            Address(token_network_address))
        if not token_network:
            return {
                'error':
                'Token network {} not found.'.format(token_network_address)
            }, 400
        try:
            paths = token_network.get_paths(source=args['from'],
                                            target=args['to'],
                                            value=args.value,
                                            k=args.num_paths)
        except NetworkXNoPath:
            return {
                'error':
                'No suitable path found for transfer from {} to {}.'.format(
                    args['from'], args['to'])
            }, 400

        return {'result': paths}, 200
Ejemplo n.º 29
0
    def _validate_token_network_argument(
            self, token_network_address: str) -> Optional[Tuple[Dict, int]]:

        if not is_address(token_network_address):
            no_address_message = 'Invalid token network address: {}'
            return {
                'error': no_address_message.format(token_network_address)
            }, 400

        if not is_checksum_address(token_network_address):
            address_error = 'Token network address not checksummed: {}'
            return {'error': address_error.format(token_network_address)}, 400

        token_network = self.pathfinding_service.token_networks.get(
            Address(token_network_address))
        if token_network is None:
            return {
                'error':
                'Unsupported token network: {}'.format(token_network_address)
            }, 400

        return None
Ejemplo n.º 30
0
def test_token_network_created(pathfinding_service_mock):
    token_address = Address("0x" + "1" * 40)
    token_network_address = TokenNetworkAddress("0x" + "2" * 40)
    network_event = ReceiveTokenNetworkCreatedEvent(
        token_address=token_address,
        token_network_address=token_network_address,
        block_number=BlockNumber(1),
    )

    assert not pathfinding_service_mock.follows_token_network(
        token_network_address)
    assert len(pathfinding_service_mock.token_networks) == 1

    pathfinding_service_mock.handle_event(network_event)
    assert pathfinding_service_mock.follows_token_network(
        token_network_address)
    assert len(pathfinding_service_mock.token_networks) == 2

    # Test idempotency
    pathfinding_service_mock.handle_event(network_event)
    assert pathfinding_service_mock.follows_token_network(
        token_network_address)
    assert len(pathfinding_service_mock.token_networks) == 2