Beispiel #1
0
    def _run(self, *args, **kwargs):
        events = query_blockchain_events(
            web3=self.web3,
            contract_manager=self._runner.contract_manager,
            contract_address=self._runner.token_network_address,
            contract_name=CONTRACT_TOKEN_NETWORK,
            topics=[],
            from_block=BlockNumber(self._runner.token_deployment_block),
            to_block=BlockNumber(self.web3.eth.blockNumber),
        )

        # Filter matching events
        events = [e for e in events if e['event'] == self.event_name]

        # Raise exception when events do not match
        if not self.num_events == len(events):
            raise ScenarioAssertionError(
                f'Expected number of events ({self.num_events}) did not match the number '
                f'of events found ({len(events)})', )
Beispiel #2
0
def test_get_filter_args(contract_manager):
    channel_identifier = factories.UNIT_CHANNEL_ID
    token_network_address = factories.UNIT_TOKEN_NETWORK_ADDRESS

    event_filter_params = get_filter_args_for_all_events_from_channel(
        token_network_address=token_network_address,
        channel_identifier=channel_identifier,
        contract_manager=contract_manager,
    )

    assert event_filter_params["topics"][0] is None
    assert to_int(
        hexstr=event_filter_params["topics"][1]) == channel_identifier
    assert event_filter_params["address"] == to_checksum_address(
        token_network_address)
    assert event_filter_params["fromBlock"] == 0
    assert event_filter_params["toBlock"] == BLOCK_ID_LATEST

    with pytest.raises(ValueError):
        # filter argument generation checks if event type is known
        get_filter_args_for_specific_event_from_channel(
            token_network_address=token_network_address,
            channel_identifier=channel_identifier,
            event_name="NonexistingEvent",
            contract_manager=contract_manager,
        )

    event_filter_params = get_filter_args_for_specific_event_from_channel(
        token_network_address=token_network_address,
        channel_identifier=channel_identifier,
        event_name="ChannelOpened",
        contract_manager=contract_manager,
        from_block=BlockNumber(100),
        to_block=BlockNumber(200),
    )

    assert event_filter_params["topics"][0] is not None
    assert to_int(
        hexstr=event_filter_params["topics"][1]) == channel_identifier
    assert event_filter_params["address"] == to_checksum_address(
        token_network_address)
    assert event_filter_params["fromBlock"] == 100
    assert event_filter_params["toBlock"] == 200
 def query_callback():
     return query_blockchain_events(
         web3=web3,
         contract_manager=contract_manager,
         contract_address=contract_address,
         contract_name=CONTRACT_TOKEN_NETWORK_REGISTRY,
         topics=[],
         from_block=BlockNumber(0),
         to_block=web3.eth.blockNumber,
     )
Beispiel #4
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
    """
    contract_data = get_contracts_deployment_info(chain_id=chain_id, version=contracts_version)
    if not contract_data:
        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(decode_hex(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
Beispiel #5
0
 def from_dict(cls, data: Dict[str, Any]) -> 'ContractReceiveRouteClosed':
     return cls(
         transaction_hash=deserialize_transactionhash(data['transaction_hash']),
         canonical_identifier=CanonicalIdentifier(
             chain_identifier=CHAIN_ID_UNSPECIFIED,
             token_network_address=to_canonical_address(data['token_network_identifier']),
             channel_identifier=ChannelID(int(data['channel_identifier'])),
         ),
         block_number=BlockNumber(int(data['block_number'])),
         block_hash=BlockHash(deserialize_bytes(data['block_hash'])),
     )
Beispiel #6
0
 def __init__(
     self,
     filename: str,
     chain_id: int,
     msc_address: Address,
     registry_address: Address,
     receiver: str,
     sync_start_block: BlockNumber = BlockNumber(0),
 ) -> None:
     super(Database, self).__init__(filename, allow_create=True)
     self._setup(chain_id, msc_address, registry_address, receiver, sync_start_block)
Beispiel #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'])),
         block_hash=BlockHash(deserialize_bytes(data['block_hash'])),
     )
def test_channel_closed_event_handler_idempotency(context: Context):
    context = setup_state_with_open_channel(context)
    context.web3.eth.blockNumber = BlockNumber(60)

    event = ReceiveChannelClosedEvent(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        channel_identifier=DEFAULT_CHANNEL_IDENTIFIER,
        closing_participant=DEFAULT_PARTICIPANT2,
        block_number=BlockNumber(52),
    )
    channel_closed_event_handler(event, context)

    # ActionMonitoringTriggeredEvent has been triggered
    assert context.database.scheduled_event_count() == 1
    assert context.database.channel_count() == 1
    assert_channel_state(context, ChannelState.CLOSED)

    # run handler again, check idempotency
    channel_closed_event_handler(event, context)
    assert context.database.scheduled_event_count() == 1
Beispiel #9
0
 def from_dict(cls, data: Dict[str,
                               Any]) -> 'ContractReceiveChannelNewBalance':
     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'])),
         deposit_transaction=data['deposit_transaction'],
         block_number=BlockNumber(int(data['block_number'])),
         block_hash=BlockHash(deserialize_bytes(data['block_hash'])),
     )
Beispiel #10
0
def test_recovery_blockchain_events(raiden_network, restart_node, token_addresses, network_wait):
    """ Close one of the two raiden apps that have a channel between them,
    have the counterparty close the channel and then make sure the restarted
    app sees the change
    """
    app0, app1 = raiden_network
    token_address = token_addresses[0]

    app0.raiden.stop()

    new_transport = MatrixTransport(
        config=app0.raiden.config.transport, environment=app0.raiden.config.environment_type
    )

    app1_api = RaidenAPI(app1.raiden)
    app1_api.channel_close(
        registry_address=app0.raiden.default_registry.address,
        token_address=token_address,
        partner_address=app0.raiden.address,
    )

    app0.stop()

    raiden_event_handler = RaidenEventHandler()
    message_handler = MessageHandler()

    app0_restart = App(
        config=app0.config,
        rpc_client=app0.raiden.rpc_client,
        proxy_manager=app0.raiden.proxy_manager,
        query_start_block=BlockNumber(0),
        default_registry=app0.raiden.default_registry,
        default_secret_registry=app0.raiden.default_secret_registry,
        default_service_registry=app0.raiden.default_service_registry,
        default_user_deposit=app0.raiden.default_user_deposit,
        default_one_to_n_address=app0.raiden.default_one_to_n_address,
        default_msc_address=app0.raiden.default_msc_address,
        transport=new_transport,
        raiden_event_handler=raiden_event_handler,
        message_handler=message_handler,
        routing_mode=RoutingMode.PRIVATE,
    )

    del app0  # from here on the app0_restart should be used

    restart_node(app0_restart)
    wal = app0_restart.raiden.wal
    assert wal

    # wait for the nodes' healthcheck to update the network statuses
    waiting.wait_for_healthy(app0_restart.raiden, app1.raiden.address, network_wait)
    waiting.wait_for_healthy(app1.raiden, app0_restart.raiden.address, network_wait)
    restarted_state_changes = wal.storage.get_statechanges_by_range(RANGE_ALL_STATE_CHANGES)
    assert search_for_item(restarted_state_changes, ContractReceiveChannelClosed, {})
Beispiel #11
0
 def from_dict(cls, data: Dict[str,
                               Any]) -> "ContractReceiveUpdateTransfer":
     return cls(
         transaction_hash=deserialize_transactionhash(
             data["transaction_hash"]),
         canonical_identifier=CanonicalIdentifier.from_dict(
             data["canonical_identifier"]),
         nonce=Nonce(int(data["nonce"])),
         block_number=BlockNumber(int(data["block_number"])),
         block_hash=BlockHash(deserialize_bytes(data["block_hash"])),
     )
Beispiel #12
0
 def from_dict(cls, data: Dict[str,
                               Any]) -> "ContractReceiveNewTokenNetwork":
     return cls(
         transaction_hash=deserialize_transactionhash(
             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"])),
         block_hash=BlockHash(deserialize_bytes(data["block_hash"])),
     )
Beispiel #13
0
 def from_dict(cls, data: Dict[str, Any]) -> "ContractReceiveRouteNew":
     return cls(
         transaction_hash=deserialize_transactionhash(
             data["transaction_hash"]),
         canonical_identifier=CanonicalIdentifier.from_dict(
             data["canonical_identifier"]),
         participant1=to_canonical_address(data["participant1"]),
         participant2=to_canonical_address(data["participant2"]),
         block_number=BlockNumber(int(data["block_number"])),
         block_hash=BlockHash(deserialize_bytes(data["block_hash"])),
     )
Beispiel #14
0
def get_pessimistic_udc_balance(udc: Contract, address: Address,
                                from_block: BlockNumber,
                                to_block: BlockNumber) -> TokenAmount:
    """Get the effective UDC balance using the block with the lowest result.

    Blocks between the latest confirmed block and the latest block are considered.
    """
    return min(
        udc.functions.effectiveBalance(address).call(
            block_identifier=BlockNumber(block))
        for block in range(from_block, to_block + 1))
Beispiel #15
0
 def from_dict(cls, data: Dict[str, Any]) -> "ContractReceiveSecretReveal":
     return cls(
         transaction_hash=deserialize_transactionhash(
             data["transaction_hash"]),
         secret_registry_address=to_canonical_address(
             data["secret_registry_address"]),
         secrethash=deserialize_secret_hash(data["secrethash"]),
         secret=deserialize_secret(data["secret"]),
         block_number=BlockNumber(int(data["block_number"])),
         block_hash=BlockHash(deserialize_bytes(data["block_hash"])),
     )
 def new_service(filename):
     service = PathfindingService(
         web3=Web3Mock(),
         private_key=server_private_key,
         contracts=contracts,
         sync_start_block=BlockNumber(0),
         required_confirmations=BlockTimeout(0),
         poll_interval=0,
         db_filename=os.path.join(tmpdir, filename),
     )
     return service
Beispiel #17
0
 def from_dict(cls, data: Dict[str,
                               Any]) -> "ContractReceiveChannelNewBalance":
     return cls(
         transaction_hash=deserialize_transactionhash(
             data["transaction_hash"]),
         canonical_identifier=CanonicalIdentifier.from_dict(
             data["canonical_identifier"]),
         deposit_transaction=data["deposit_transaction"],
         block_number=BlockNumber(int(data["block_number"])),
         block_hash=BlockHash(deserialize_bytes(data["block_hash"])),
     )
Beispiel #18
0
 def make_request() -> BlockNumber:
     response = requests.get(
         "https://api.blockcypher.com/v1/eth/main",
         headers={
             "ACCEPT":
             "application/json",
             "USER-AGENT":
             f"raiden-{pkg_resources.require(raiden.__name__)[0].version}",
         },
     )
     return BlockNumber(json.loads(response.content)["height"])
def test_channel_settled_event_handler_settles_existing_channel(context: Context):
    context = setup_state_with_closed_channel(context)

    event = ReceiveChannelSettledEvent(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        channel_identifier=DEFAULT_CHANNEL_IDENTIFIER,
        block_number=BlockNumber(52),
    )
    channel_settled_event_handler(event, context)

    assert context.database.channel_count() == 1
    assert_channel_state(context, ChannelState.SETTLED)
Beispiel #20
0
def test_blockchain_events(contract_manager):
    # TODO Expand this test: multiple listeners, removed listeners, multiple/missed events.
    # As it is now it only covers the classès helper functions in raiden.utils.filters properly.
    blockchain_events = BlockchainEvents(UNIT_CHAIN_ID)
    abi = contract_manager.get_contract_abi("TokenNetwork")

    stateless_filter = StatelessFilter(web3=stub_web3(event_logs),
                                       filter_params=dict(toBlock="pending"))
    blockchain_events.add_event_listener(event_name="Block",
                                         eth_filter=stateless_filter,
                                         abi=abi)

    events = list(
        blockchain_events.poll_blockchain_events(
            block_number=BlockNumber(235)))

    assert len(events) == 1
    assert len(stateless_filter.get_all_entries(BlockNumber(235))) == 1
    assert check_dict_nested_attrs(events[0].event_data, event1)

    blockchain_events.uninstall_all_event_listeners()
Beispiel #21
0
def setup_channel(pathfinding_service_mock, token_network_model):
    channel_event = ReceiveChannelOpenedEvent(
        token_network_address=token_network_model.address,
        channel_identifier=ChannelID(1),
        participant1=PARTICIPANT1,
        participant2=PARTICIPANT2,
        settle_timeout=20,
        block_number=BlockNumber(1),
    )
    assert len(pathfinding_service_mock.token_networks) == 1
    assert len(token_network_model.channel_id_to_addresses) == 0
    pathfinding_service_mock.handle_event(channel_event)
def test_get_blockchain_events_adaptive_reduces_block_interval_after_timeout(
        web3: Web3, token_network_registry_contract: Contract):
    chain_state = BlockchainState(
        chain_id=ChainID(1),
        token_network_registry_address=to_canonical_address(
            token_network_registry_contract.address),
        latest_committed_block=BlockNumber(4),
    )

    assert chain_state.current_event_filter_interval == DEFAULT_FILTER_INTERVAL

    with patch("raiden_libs.blockchain.get_blockchain_events",
               side_effect=ReadTimeout):
        _ = get_blockchain_events_adaptive(
            web3=web3,
            token_network_addresses=[],
            blockchain_state=chain_state,
            latest_confirmed_block=BlockNumber(1),
        )

        assert chain_state.current_event_filter_interval == DEFAULT_FILTER_INTERVAL // 5
Beispiel #23
0
def test_channel_settled_event_handler_leaves_existing_channel(context: Context,):
    context = setup_state_with_closed_channel(context)

    event = ReceiveChannelSettledEvent(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        channel_identifier=ChannelID(4),
        block_number=BlockNumber(52),
    )
    channel_settled_event_handler(event, context)

    assert context.db.channel_count() == 1
    assert_channel_state(context, ChannelState.CLOSED)
Beispiel #24
0
def test_channel_bp_updated_event_handler_sets_update_status_if_not_set(context: Context,):
    context = setup_state_with_closed_channel(context)

    event_bp = ReceiveNonClosingBalanceProofUpdatedEvent(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        channel_identifier=DEFAULT_CHANNEL_IDENTIFIER,
        closing_participant=DEFAULT_PARTICIPANT2,
        nonce=Nonce(2),
        block_number=BlockNumber(23),
    )

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

    non_closing_balance_proof_updated_event_handler(event_bp, context)

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

    event_bp2 = ReceiveNonClosingBalanceProofUpdatedEvent(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        channel_identifier=DEFAULT_CHANNEL_IDENTIFIER,
        closing_participant=DEFAULT_PARTICIPANT2,
        nonce=Nonce(5),
        block_number=BlockNumber(53),
    )

    non_closing_balance_proof_updated_event_handler(event_bp2, context)

    assert context.db.channel_count() == 1
    channel = context.db.get_channel(event_bp.token_network_address, event_bp.channel_identifier)
    assert channel
    assert channel.update_status is not None
    assert channel.update_status.nonce == 5
    assert channel.update_status.update_sender_address == DEFAULT_PARTICIPANT1
Beispiel #25
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)
Beispiel #26
0
def deploy_secret_registry(deploy_client: JSONRPCClient,
                           contract_manager: ContractManager,
                           proxy_manager: ProxyManager) -> SecretRegistry:
    contract, receipt = deploy_client.deploy_single_contract(
        contract_name=CONTRACT_SECRET_REGISTRY,
        contract=contract_manager.get_contract(CONTRACT_SECRET_REGISTRY),
        constructor_parameters=None,
    )

    return proxy_manager.secret_registry(
        SecretRegistryAddress(to_canonical_address(contract.address)),
        BlockNumber(receipt["blockNumber"]),
    )
Beispiel #27
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'])),
     )
def test_channel_closed_event_handler_trigger_action_monitor_event_without_monitor_request(
    context: Context, ):
    context = setup_state_with_open_channel(context)

    event = ReceiveChannelClosedEvent(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        channel_identifier=DEFAULT_CHANNEL_IDENTIFIER,
        closing_participant=DEFAULT_PARTICIPANT2,
        block_number=BlockNumber(52),
    )

    channel_closed_event_handler(event, context)
    assert context.db.scheduled_event_count() == 1
def test_channel_closed_event_handler_leaves_existing_channel(context: Context):
    context = setup_state_with_open_channel(context)

    event = ReceiveChannelClosedEvent(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        channel_identifier=ChannelID(4),
        closing_participant=DEFAULT_PARTICIPANT2,
        block_number=BlockNumber(52),
    )
    channel_closed_event_handler(event, context)

    assert context.db.channel_count() == 1
    assert_channel_state(context, ChannelState.OPENED)
Beispiel #30
0
def test_metrics_iou(  # pylint: disable=too-many-locals
    pathfinding_service_web3_mock: PathfindingService,
    one_to_n_contract,
    web3: Web3,
    deposit_to_udc,
    get_accounts,
    get_private_key,
):
    pfs = pathfinding_service_web3_mock

    metrics_state = save_metrics_state(metrics.REGISTRY)
    # Prepare test data
    account = [decode_hex(acc) for acc in get_accounts(1)][0]
    local_signer = LocalSigner(private_key=get_private_key(account))
    iou = IOU(
        sender=account,
        receiver=pfs.address,
        amount=TokenAmount(100),
        expiration_block=BlockNumber(100),
        signature=Signature(bytes([1] * 64)),
        chain_id=ChainID(61),
        one_to_n_address=to_canonical_address(one_to_n_contract.address),
        claimed=False,
    )
    iou.signature = Signature(local_signer.sign(iou.packed_data()))
    pfs.database.upsert_iou(iou)
    deposit_to_udc(iou.sender, 300)

    # Claim IOUs
    skipped, failures = claim_ious(
        ious=[iou],
        claim_cost_rdn=TokenAmount(100),
        one_to_n_contract=one_to_n_contract,
        web3=web3,
        database=pfs.database,
    )
    assert (skipped, failures) == (0, 0)

    assert (
        metrics_state.get_delta(
            "economics_iou_claims_total", labels=metrics.IouStatus.SUCCESSFUL.to_label_dict()
        )
        == 1.0
    )
    assert (
        metrics_state.get_delta(
            "economics_iou_claims_token_total",
            labels=metrics.IouStatus.SUCCESSFUL.to_label_dict(),
        )
        == 100.0
    )