Exemple #1
0
def get_contract_events(
    proxy_manager: ProxyManager,
    abi: ABI,
    contract_address: Address,
    topics: Optional[List[str]] = ALL_EVENTS,
    from_block: BlockIdentifier = GENESIS_BLOCK_NUMBER,
    to_block: BlockIdentifier = BLOCK_ID_LATEST,
) -> List[Dict]:
    """Query the blockchain for all events of the smart contract at
    `contract_address` that match the filters `topics`, `from_block`, and
    `to_block`.
    """
    verify_block_number(from_block, "from_block")
    verify_block_number(to_block, "to_block")
    events = proxy_manager.client.get_filter_events(
        contract_address, topics=topics, from_block=from_block, to_block=to_block
    )

    result = []
    for event in events:
        decoded_event = dict(decode_event(abi, event))
        if event.get("blockNumber"):
            decoded_event["block_number"] = event["blockNumber"]
            del decoded_event["blockNumber"]
        result.append(decoded_event)
    return result
Exemple #2
0
def get_channel_participants_from_open_event(
    token_network: "TokenNetwork",
    channel_identifier: ChannelID,
    contract_manager: ContractManager,
    from_block: BlockNumber,
) -> Optional[Tuple[Address, Address]]:
    # For this check it is perfectly fine to use a `latest` block number.
    # Because the filter is looking just for the OPENED event.
    to_block = "latest"

    filter_args = get_filter_args_for_specific_event_from_channel(
        token_network_address=token_network.address,
        channel_identifier=channel_identifier,
        event_name=ChannelEvent.OPENED,
        contract_manager=contract_manager,
        from_block=from_block,
        to_block=to_block,
    )

    events = token_network.proxy.contract.web3.eth.getLogs(filter_args)

    # There must be only one channel open event per channel identifier
    if len(events) != 1:
        return None

    event = decode_event(
        contract_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK), events[0])
    participant1 = Address(decode_hex(event["args"]["participant1"]))
    participant2 = Address(decode_hex(event["args"]["participant2"]))

    return participant1, participant2
Exemple #3
0
def find_deposits(
    web3: Web3,
    service_address: Address,
    service_registry_contract: Contract,
    start_block: BlockNumber,
) -> List[Dict[str, Any]]:
    """
    Return the address of the oldest deposit contract which is not withdrawn
    """
    # Get RegisteredService events for service_address
    event_abi = dict(
        service_registry_contract.events[EVENT_REGISTERED_SERVICE]().abi)
    topics = [
        event_abi_to_log_topic(event_abi),
        bytes([0] * 12) + service_address,
    ]
    filter_params = FilterParams({
        "fromBlock":
        start_block,
        "toBlock":
        "latest",
        "address":
        service_registry_contract.address,
        "topics": [HexStr("0x" + t.hex()) for t in topics],
    })
    raw_events = web3.eth.getLogs(filter_params)
    events = [
        decode_event(service_registry_contract.abi, event)
        for event in raw_events
    ]

    # Bring events into a pleasant form
    return [
        dict(
            block_number=e["blockNumber"],
            valid_till=datetime.utcfromtimestamp(
                e["args"]["valid_till"]).isoformat(" "),
            amount=e["args"]["deposit_amount"],
            deposit_contract=e["args"]["deposit_contract"],
            withdrawn=not web3.eth.getCode(e["args"]["deposit_contract"]),
        ) for e in events
    ]
Exemple #4
0
    def settle_timeout(self) -> BlockTimeout:
        """ Returns the channels settle_timeout. """

        # There is no way to get the settle timeout after the channel has been closed as
        # we're saving gas. Therefore get the ChannelOpened event and get the timeout there.
        filter_args = get_filter_args_for_specific_event_from_channel(
            token_network_address=self.token_network.address,
            channel_identifier=self.channel_identifier,
            event_name=ChannelEvent.OPENED,
            contract_manager=self.contract_manager,
        )

        events = self.client.web3.eth.getLogs(filter_args)
        assert len(events) > 0, "No matching ChannelOpen event found."

        # we want the latest event here, there might have been multiple channels
        event = decode_event(
            self.contract_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK),
            events[-1])
        return event["args"]["settle_timeout"]
Exemple #5
0
    def close_block_number(self) -> Optional[BlockNumber]:
        """ Returns the channel's closed block number. """

        # The closed block number is not in the smart contract storage to save
        # gas. Therefore get the ChannelClosed event is needed here.
        filter_args = get_filter_args_for_specific_event_from_channel(
            token_network_address=self.token_network.address,
            channel_identifier=self.channel_identifier,
            event_name=ChannelEvent.CLOSED,
            contract_manager=self.contract_manager,
        )

        events = self.token_network.proxy.contract.web3.eth.getLogs(
            filter_args)
        if not events:
            return None

        assert len(events) == 1
        event = decode_event(
            self.contract_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK),
            events[0])
        return event["blockNumber"]
Exemple #6
0
 def decode_event(self, log: Dict[str, Any]) -> Dict[str, Any]:
     return decode_event(self.contract.abi, log)
Exemple #7
0
def decode_raiden_event_to_internal(
    abi: ABI, chain_id: ChainID, log_event: LogReceipt
) -> DecodedEvent:
    """Enforce the sandwich encoding. Converts the JSON RPC/web3 data types
    to the internal representation.

    Note::

        This function must only on confirmed data.
    """
    # Note: All addresses inside the event_data must be decoded.

    decoded_event = decode_event(abi, log_event)

    if not decoded_event:
        raise UnknownRaidenEventType()

    # copy the attribute dict because that data structure is immutable
    data = dict(decoded_event)
    args = dict(decoded_event["args"])

    data["args"] = args
    # translate from web3's to raiden's name convention
    data["block_number"] = log_event["blockNumber"]
    data["transaction_hash"] = log_event["transactionHash"]
    data["block_hash"] = bytes(log_event["blockHash"])

    # Remove the old names
    del data["blockNumber"]
    del data["transactionHash"]
    del data["blockHash"]

    assert data["block_number"], "The event must have the block_number"
    assert data["transaction_hash"], "The event must have the transaction hash field"
    assert data["block_hash"], "The event must have the block_hash"

    event = data["event"]
    if event == EVENT_TOKEN_NETWORK_CREATED:
        args["token_network_address"] = to_canonical_address(args["token_network_address"])
        args["token_address"] = to_canonical_address(args["token_address"])

    elif event == ChannelEvent.OPENED:
        args["participant1"] = to_canonical_address(args["participant1"])
        args["participant2"] = to_canonical_address(args["participant2"])

    elif event == ChannelEvent.DEPOSIT:
        args["participant"] = to_canonical_address(args["participant"])

    elif event == ChannelEvent.WITHDRAW:
        args["participant"] = to_canonical_address(args["participant"])

    elif event == ChannelEvent.BALANCE_PROOF_UPDATED:
        args["closing_participant"] = to_canonical_address(args["closing_participant"])

    elif event == ChannelEvent.CLOSED:
        args["closing_participant"] = to_canonical_address(args["closing_participant"])

    elif event == ChannelEvent.UNLOCKED:
        args["receiver"] = to_canonical_address(args["receiver"])
        args["sender"] = to_canonical_address(args["sender"])

    return DecodedEvent(
        chain_id=chain_id,
        originating_contract=to_canonical_address(log_event["address"]),
        event_data=data,
        block_number=log_event["blockNumber"],
        block_hash=BlockHash(log_event["blockHash"]),
        transaction_hash=TransactionHash(log_event["transactionHash"]),
    )
Exemple #8
0
 def decode_event(self, log: Dict):
     return decode_event(self.contract.abi, log)