Пример #1
0
def get_netting_channel_deposit_events(
        chain: BlockChainService,
        token_network_address: Address,
        netting_channel_identifier: ChannelID,
        contract_manager: ContractManager,
        from_block: BlockSpecification = GENESIS_BLOCK_NUMBER,
        to_block: BlockSpecification = 'latest',
) -> List[Dict]:
    deposit_event_abi = contract_manager.get_event_abi(
        CONTRACT_TOKEN_NETWORK,
        ChannelEvent.DEPOSIT,
    )
    topic_set = construct_event_topic_set(
        event_abi=deposit_event_abi,
        arguments={'channel_identifier': netting_channel_identifier},
    )

    if len(topic_set) == 1 and is_list_like(topic_set[0]):
        topics = topic_set[0]
    else:
        topics = topic_set

    return get_contract_events(
        chain,
        contract_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK),
        token_network_address,
        topics,
        from_block,
        to_block,
    )
Пример #2
0
def get_or_deploy_token(runner) -> ContractProxy:
    """ Deploy or reuse  """
    contract_manager = ContractManager(contracts_precompiled_path())
    token_contract = contract_manager.get_contract(CONTRACT_CUSTOM_TOKEN)

    token_config = runner.scenario.get('token', {})
    if not token_config:
        token_config = {}
    address = token_config.get('address')
    reuse = token_config.get('reuse', False)

    token_address_file = runner.data_path.joinpath('token.addr')
    if reuse:
        if address:
            raise ScenarioError('Token settings "address" and "reuse" are mutually exclusive.')
        if token_address_file.exists():
            address = token_address_file.read_text()
    if address:
        check_address_has_code(runner.client, address, 'Token')
        token_ctr = runner.client.new_contract_proxy(token_contract['abi'], address)

        log.debug(
            "Reusing token",
            address=to_checksum_address(address),
            name=token_ctr.contract.functions.name().call(),
            symbol=token_ctr.contract.functions.symbol().call(),
        )
        return token_ctr

    token_id = uuid.uuid4()
    now = datetime.now()
    name = token_config.get('name', f"Scenario Test Token {token_id!s} {now:%Y-%m-%dT%H:%M}")
    symbol = token_config.get('symbol', f"T{token_id!s:.3}")
    decimals = token_config.get('decimals', 0)

    log.debug("Deploying token", name=name, symbol=symbol, decimals=decimals)

    token_ctr = runner.client.deploy_solidity_contract(
        'CustomToken',
        contract_manager.contracts,
        constructor_parameters=(0, decimals, name, symbol),
    )
    contract_checksum_address = to_checksum_address(token_ctr.contract_address)
    if reuse:
        token_address_file.write_text(contract_checksum_address)

    log.info(
        "Deployed token",
        address=contract_checksum_address,
        name=name,
        symbol=symbol,
    )
    return token_ctr
Пример #3
0
    def __init__(
            self,
            jsonrpc_client,
            discovery_address,
            contract_manager: ContractManager,
    ):
        contract = jsonrpc_client.new_contract(
            contract_manager.get_contract_abi(CONTRACT_ENDPOINT_REGISTRY),
            to_normalized_address(discovery_address),
        )
        proxy = ContractProxy(jsonrpc_client, contract)

        if not is_binary_address(discovery_address):
            raise ValueError('discovery_address must be a valid address')

        check_address_has_code(jsonrpc_client, discovery_address, 'Discovery')

        compare_contract_versions(
            proxy=proxy,
            expected_version=contract_manager.contracts_version,
            contract_name=CONTRACT_ENDPOINT_REGISTRY,
            address=discovery_address,
        )

        self.address = discovery_address
        self.node_address = privatekey_to_address(jsonrpc_client.privkey)
        self.client = jsonrpc_client
        self.not_found_address = NULL_ADDRESS
        self.proxy = proxy
Пример #4
0
def get_filter_args_for_specific_event_from_channel(
        token_network_address: TokenNetworkAddress,
        channel_identifier: ChannelID,
        event_name: str,
        contract_manager: ContractManager,
        from_block: BlockSpecification = GENESIS_BLOCK_NUMBER,
        to_block: BlockSpecification = 'latest',
):
    """ Return the filter params for a specific event of a given channel. """
    if not event_name:
        raise ValueError('Event name must be given')

    event_abi = contract_manager.get_event_abi(CONTRACT_TOKEN_NETWORK, event_name)

    # Here the topics for a specific event are created
    # The first entry of the topics list is the event name, then the first parameter is encoded,
    # in the case of a token network, the first parameter is always the channel identifier
    _, event_filter_params = construct_event_filter_params(
        event_abi=event_abi,
        contract_address=to_checksum_address(token_network_address),
        argument_filters={
            'channel_identifier': channel_identifier,
        },
        fromBlock=from_block,
        toBlock=to_block,
    )

    return event_filter_params
Пример #5
0
def deploy_token(
        deploy_client: JSONRPCClient,
        contract_manager: ContractManager,
        initial_amount: typing.TokenAmount,
        decimals: int,
        token_name: str,
        token_symbol: str,
)-> ContractProxy:
    token_address = deploy_contract_web3(
        contract_name=CONTRACT_HUMAN_STANDARD_TOKEN,
        deploy_client=deploy_client,
        contract_manager=contract_manager,
        constructor_arguments=(
            initial_amount,
            decimals,
            token_name,
            token_symbol,
        ),
    )

    contract_abi = contract_manager.get_contract_abi(CONTRACT_HUMAN_STANDARD_TOKEN)
    return deploy_client.new_contract_proxy(
        contract_interface=contract_abi,
        contract_address=token_address,
    )
Пример #6
0
def deploy_contract_web3(
        contract_name: str,
        deploy_client: JSONRPCClient,
        contract_manager: ContractManager,
        constructor_arguments: typing.Tuple[typing.Any, ...] = (),
) -> typing.Address:
    compiled = {
        contract_name: contract_manager.get_contract(contract_name),
    }
    contract_proxy = deploy_client.deploy_solidity_contract(
        contract_name,
        compiled,
        constructor_parameters=constructor_arguments,
    )
    return typing.Address(to_canonical_address(contract_proxy.contract.address))
Пример #7
0
class ContractTester:
    def __init__(self, generate_keys=0):
        self.tester = EthereumTester(PyEVMBackend())
        self.web3 = Web3(EthereumTesterProvider(self.tester))
        if generate_keys > 0:
            generated_keys = [urandom(32) for _ in range(generate_keys)]
            self.private_keys = [PrivateKey(key) for key in generated_keys]
            self.accounts = [
                self.tester.add_account(f'{encode_hex(key)}')
                for key in generated_keys
            ]
            for account in self.accounts:
                self.tester.send_transaction({
                    'from': self.tester.get_accounts()[0],
                    'to': account,
                    'value': 10 ** 21,
                    'gas': 21000,
                })
        else:
            self.accounts = self.tester.get_accounts()
        self.contract_manager = ContractManager(CONTRACTS_SOURCE_DIRS)
        self.name_to_creation_hash = dict()
        self.name_to_contract = dict()

    def deploy_contract(self, name, **kwargs):
        data = self.contract_manager.get_contract(name)
        contract = self.web3.eth.contract(abi=data['abi'], bytecode=data['bin'])
        transaction = contract.constructor(**kwargs).buildTransaction({
            'from': self.accounts[0],
            'gas': 5900000,
        })
        self.name_to_creation_hash[name] = self.web3.eth.sendTransaction(transaction)
        self.name_to_contract[name] = self.web3.eth.contract(
            address=self.contract_address(name),
            abi=data['abi'],
        )

    def contract_address(self, name):
        tx_hash = self.name_to_creation_hash[name]
        return self.web3.eth.getTransactionReceipt(tx_hash)['contractAddress']

    def call_transaction(self, contract, function, **kwargs):
        sender = kwargs.pop('sender', self.accounts[0])
        tx_hash = self.name_to_contract[contract].functions[function](**kwargs).transact({
            'from': sender,
        })
        return self.web3.eth.getTransactionReceipt(tx_hash)
Пример #8
0
    def __init__(
            self,
            jsonrpc_client,
            token_address,
            contract_manager: ContractManager,
    ):
        contract = jsonrpc_client.new_contract(
            contract_manager.get_contract_abi(CONTRACT_HUMAN_STANDARD_TOKEN),
            to_normalized_address(token_address),
        )
        proxy = ContractProxy(jsonrpc_client, contract)

        if not is_binary_address(token_address):
            raise ValueError('token_address must be a valid address')

        check_address_has_code(jsonrpc_client, token_address, 'Token')

        self.address = token_address
        self.client = jsonrpc_client
        self.node_address = privatekey_to_address(jsonrpc_client.privkey)
        self.proxy = proxy
Пример #9
0
    def __init__(
        self,
        jsonrpc_client: JSONRPCClient,
        user_deposit_address: UserDepositAddress,
        contract_manager: ContractManager,
        proxy_manager: "ProxyManager",
        block_identifier: BlockIdentifier,
    ) -> None:
        if not is_binary_address(user_deposit_address):
            raise ValueError("Expected binary address format for token nework")

        check_address_has_code_handle_pruned_block(
            client=jsonrpc_client,
            address=Address(user_deposit_address),
            contract_name=CONTRACT_USER_DEPOSIT,
            expected_code=decode_hex(contract_manager.get_runtime_hexcode(CONTRACT_USER_DEPOSIT)),
            given_block_identifier=block_identifier,
        )

        self.client = jsonrpc_client

        self.address = user_deposit_address
        self.node_address = self.client.address
        self.contract_manager = contract_manager
        self.gas_measurements = gas_measurements(self.contract_manager.contracts_version)

        self.proxy_manager = proxy_manager

        self.proxy = jsonrpc_client.new_contract_proxy(
            abi=self.contract_manager.get_contract_abi(CONTRACT_USER_DEPOSIT),
            contract_address=Address(user_deposit_address),
        )

        # Keeps track of the current in-flight deposits, to avoid sending
        # unecessary transactions.
        self._inflight_deposits: Dict[Address, InflightDeposit] = dict()

        # Don't allow concurrent withdraw_plan and withdraw calls.
        # This simplifies the precondition checks.
        self._withdraw_lock = Lock()
Пример #10
0
def query_blockchain_events(
        web3: Web3,
        contract_manager: ContractManager,
        contract_address: Address,
        contract_name: str,
        topics: List,
        from_block: BlockNumber,
        to_block: BlockNumber,
) -> List[Dict]:
    """Returns events emmitted by a contract for a given event name, within a certain range.

    Args:
        web3: A Web3 instance
        contract_manager: A contract manager
        contract_address: The address of the contract to be filtered, can be `None`
        contract_name: The name of the contract
        topics: The topics to filter for
        from_block: The block to start search events
        to_block: The block to stop searching for events

    Returns:
        All matching events
    """
    filter_params = {
        'fromBlock': from_block,
        'toBlock': to_block,
        'address': to_checksum_address(contract_address),
        'topics': topics,
    }

    events = web3.eth.getLogs(filter_params)

    contract_abi = contract_manager.get_contract_abi(contract_name)
    return [
        decode_event(
            abi=contract_abi,
            log_=raw_event,
        )
        for raw_event in events
    ]
def test_alderaan_version() -> None:
    """ contracts_source_path('0.37.0') exists and contains the expected files """
    contract_names = [
        "Utils",
        "SecretRegistry",
        "TokenNetworkRegistry",
        "TokenNetwork",
        "ServiceRegistry",
        "MonitoringService",
        "UserDeposit",
        "OneToN",
    ]

    manager = ContractManager(contracts_precompiled_path(ALDERAAN_VERSION))
    assert manager.contracts_version == ALDERAAN_VERSION
    check_precompiled_content(manager, contract_names, PRECOMPILED_DATA_FIELDS)

    assert contracts_precompiled_path(ALDERAAN_VERSION).exists()
    assert contracts_deployed_path(CHAINNAME_TO_ID["mainnet"], ALDERAAN_VERSION).exists()
    assert contracts_deployed_path(CHAINNAME_TO_ID["rinkeby"], ALDERAAN_VERSION).exists()
    assert contracts_deployed_path(CHAINNAME_TO_ID["ropsten"], ALDERAAN_VERSION).exists()
    assert contracts_deployed_path(CHAINNAME_TO_ID["goerli"], ALDERAAN_VERSION).exists()
Пример #12
0
    def compile_contracts(self, target_path: Path) -> ContractManager:
        """Store compiled contracts JSON at `target_path`."""
        assert self.overall_checksum is not None

        contracts_compiled = self._compile_all_contracts()

        target_path.parent.mkdir(parents=True, exist_ok=True)
        with target_path.open(mode="w") as target_file:
            target_file.write(
                json.dumps(
                    dict(
                        contracts=contracts_compiled,
                        contracts_checksums=self.contracts_checksums,
                        overall_checksum=self.overall_checksum,
                        contracts_version=None,
                    ),
                    sort_keys=True,
                    indent=4,
                )
            )

        return ContractManager(target_path)
Пример #13
0
    def __init__(
        self,
        jsonrpc_client: JSONRPCClient,
        secret_registry_address: Address,
        contract_manager: ContractManager,
    ) -> None:
        if not is_binary_address(secret_registry_address):
            raise ValueError(
                "Expected binary address format for secret registry")

        self.contract_manager = contract_manager
        check_address_has_code(
            client=jsonrpc_client,
            address=secret_registry_address,
            contract_name=CONTRACT_SECRET_REGISTRY,
            expected_code=decode_hex(
                contract_manager.get_runtime_hexcode(
                    CONTRACT_SECRET_REGISTRY)),
        )

        proxy = jsonrpc_client.new_contract_proxy(
            abi=self.contract_manager.get_contract_abi(
                CONTRACT_SECRET_REGISTRY),
            contract_address=secret_registry_address,
        )

        # There should be only one smart contract deployed, to avoid race
        # conditions for on-chain unlocks.

        self.address = secret_registry_address
        self.proxy = proxy
        self.client = jsonrpc_client
        self.node_address = self.client.address

        # The dictionary of open transactions is used to avoid sending a
        # transaction for the same secret more than once. This requires
        # synchronization for the local threads.
        self.open_secret_transactions: Dict[Secret, AsyncResult] = dict()
        self._open_secret_transactions_lock = Semaphore()
def test_pre_limits_version() -> None:
    """ contracts_source_path('0.3._') exists and contains the expected files """
    contracts_version = "0.3._"
    contract_names = [
        "Utils",
        "EndpointRegistry",
        "SecretRegistry",
        "TokenNetworkRegistry",
        "TokenNetwork",
    ]

    manager = ContractManager(contracts_precompiled_path(contracts_version))
    assert manager.contracts_version == contracts_version
    check_precompiled_content(manager, contract_names, PRECOMPILED_DATA_FIELDS)

    assert contracts_precompiled_path(contracts_version).exists()
    assert contracts_deployed_path(NETWORKNAME_TO_ID["rinkeby"],
                                   contracts_version).exists()
    assert contracts_deployed_path(NETWORKNAME_TO_ID["ropsten"],
                                   contracts_version).exists()
    assert contracts_deployed_path(NETWORKNAME_TO_ID["kovan"],
                                   contracts_version).exists()
Пример #15
0
def deploy_one_to_n(
    user_deposit_deploy_result: Callable[[], UserDeposit],
    service_registry_deploy_result: Callable[[], ServiceRegistry],
    deploy_client: JSONRPCClient,
    contract_manager: ContractManager,
    proxy_manager: ProxyManager,
    chain_id: ChainID,
) -> OneToN:
    user_deposit_proxy = user_deposit_deploy_result()
    service_registry_proxy = service_registry_deploy_result()
    contract, receipt = deploy_client.deploy_single_contract(
        contract_name=CONTRACT_ONE_TO_N,
        contract=contract_manager.get_contract(CONTRACT_ONE_TO_N),
        constructor_parameters=[
            user_deposit_proxy.address,
            chain_id,
            service_registry_proxy.address,
        ],
    )
    return proxy_manager.one_to_n(
        OneToNAddress(to_canonical_address(contract.address)),
        BlockNumber(receipt["blockNumber"]))
def test_pre_limits_version():
    """ contracts_source_path('0.3._') exists and contains the expected files """
    contracts_version = '0.3._'
    contract_names = [
        'Utils',
        'EndpointRegistry',
        'SecretRegistry',
        'TokenNetworkRegistry',
        'TokenNetwork',
    ]

    manager = ContractManager(contracts_precompiled_path(contracts_version))
    assert manager.contracts_version == contracts_version
    check_precompiled_content(manager, contract_names, PRECOMPILED_DATA_FIELDS)

    assert contracts_precompiled_path(contracts_version).exists()
    assert contracts_deployed_path(NETWORKNAME_TO_ID['rinkeby'],
                                   contracts_version).exists()
    assert contracts_deployed_path(NETWORKNAME_TO_ID['ropsten'],
                                   contracts_version).exists()
    assert contracts_deployed_path(NETWORKNAME_TO_ID['kovan'],
                                   contracts_version).exists()
Пример #17
0
 def __init__(self, generate_keys=0):
     self.tester = EthereumTester(PyEVMBackend())
     self.web3 = Web3(EthereumTesterProvider(self.tester))
     if generate_keys > 0:
         self.private_keys = [urandom(32) for _ in range(generate_keys)]
         self.accounts = [self.tester.add_account(encode_hex(key)) for key in self.private_keys]
         for account in self.accounts:
             self.tester.send_transaction(
                 {
                     "from": self.tester.get_accounts()[0],
                     "to": account,
                     "value": 10 ** 21,
                     "gas": 21000,
                 }
             )
     else:
         self.accounts = self.tester.get_accounts()
     self.contract_manager = ContractManager(
         contracts_precompiled_path(RAIDEN_CONTRACT_VERSION)
     )
     self.name_to_creation_hash: Dict[str, bytes] = dict()
     self.name_to_contract: Dict[str, str] = dict()
Пример #18
0
 def __init__(self, generate_keys=0):
     self.tester = EthereumTester(PyEVMBackend())
     self.web3 = Web3(EthereumTesterProvider(self.tester))
     if generate_keys > 0:
         generated_keys = [urandom(32) for _ in range(generate_keys)]
         self.private_keys = [PrivateKey(key) for key in generated_keys]
         self.accounts = [
             self.tester.add_account(f'{encode_hex(key)}')
             for key in generated_keys
         ]
         for account in self.accounts:
             self.tester.send_transaction({
                 'from': self.tester.get_accounts()[0],
                 'to': account,
                 'value': 10 ** 21,
                 'gas': 21000,
             })
     else:
         self.accounts = self.tester.get_accounts()
     self.contract_manager = ContractManager(CONTRACTS_SOURCE_DIRS)
     self.name_to_creation_hash = dict()
     self.name_to_contract = dict()
Пример #19
0
def test_current_development_version():
    """ contracts_source_path() exists and contains the expected files """
    contracts_version = CONTRACTS_VERSION
    contract_names = [
        'Utils',
        'EndpointRegistry',
        'SecretRegistry',
        'TokenNetworkRegistry',
        'TokenNetwork',
        'MonitoringService',
        'ServiceRegistry',
    ]

    manager = ContractManager(contracts_precompiled_path(contracts_version))
    assert manager.contracts_version == contracts_version
    check_precompiled_content(manager, contract_names, PRECOMPILED_DATA_FIELDS)

    for _, source_path in contracts_source_path().items():
        assert source_path.exists()
    assert contracts_precompiled_path().exists()

    # deployment files exist
    assert contracts_deployed_path(NETWORKNAME_TO_ID['rinkeby']).exists()
    assert contracts_deployed_path(NETWORKNAME_TO_ID['ropsten']).exists()
    assert contracts_deployed_path(NETWORKNAME_TO_ID['kovan']).exists()
    # deployment files for service contracts also exist
    assert contracts_deployed_path(
        NETWORKNAME_TO_ID['rinkeby'],
        services=True,
    ).exists()
    assert contracts_deployed_path(
        NETWORKNAME_TO_ID['ropsten'],
        services=True,
    ).exists()
    assert contracts_deployed_path(
        NETWORKNAME_TO_ID['kovan'],
        services=True,
    ).exists()
    def verify_precompiled_checksums(self, precompiled_path: Path) -> None:
        """Compare source code checksums with those from a precompiled file

        If `contract_name` is None, all contracts checksums and the overall checksum are checked.
        """

        # We get the precompiled file data
        contracts_precompiled = ContractManager(precompiled_path)

        # Compare each contract source code checksum with the one from the precompiled file
        for contract, checksum in self.contracts_checksums.items():
            _verify_single_precompiled_checksum(
                checked_checksums=contracts_precompiled.contracts_checksums,
                contract_name=contract,
                expected_checksum=checksum,
            )

        # Compare the overall source code checksum with the one from the precompiled file
        if self.overall_checksum != contracts_precompiled.overall_checksum:
            raise ContractSourceManagerVerificationError(
                f"overall checksum does not match "
                f"{self.overall_checksum} != {contracts_precompiled.overall_checksum}"
            )
Пример #21
0
def _verify_singleton_contract(
    chain_id: ChainID,
    apikey: str,
    source_module: DeploymentModule,
    contract_name: str,
) -> None:
    """ Calls Etherscan API for verifying the Solidity source of a contract.

    This function can only be used to verify contracts which are only deployed
    once. E.g. `TokenNetworkRegistry`, but not `TokenNetwork`.
    Args:
        chain_id: EIP-155 chain id of the Ethereum chain
        apikey: key for calling Etherscan API
        source_module: a module name to look up contracts_source_path()
        contract_name: 'TokenNetworkRegistry', 'SecretRegistry' etc.
    """

    deployment_info = get_contracts_deployment_info(chain_id=chain_id,
                                                    module=source_module)
    assert deployment_info
    contract_manager = ContractManager(contracts_precompiled_path())
    metadata = json.loads(
        contract_manager.contracts[contract_name]["metadata"])
    constructor_args = get_constructor_args(
        deployment_info=deployment_info,
        contract_name=contract_name,
        contract_manager=contract_manager,
    )
    contract_deploy_info = deployment_info["contracts"][contract_name]
    etherscan_verify_contract(
        chain_id=chain_id,
        apikey=apikey,
        address=contract_deploy_info["address"],
        contract_name=contract_name,
        metadata=metadata,
        constructor_args=constructor_args,
    )
Пример #22
0
    def compile_contracts(self, target_path: Path) -> ContractManager:
        """ Store compiled contracts JSON at `target_path`. """
        self.checksum_contracts()

        if self.overall_checksum is None:
            raise ContractSourceManagerCompilationError("Checksumming failed.")

        contracts_compiled = self._compile_all_contracts()

        target_path.parent.mkdir(parents=True, exist_ok=True)
        with target_path.open(mode="w") as target_file:
            target_file.write(
                json.dumps(
                    dict(
                        contracts=contracts_compiled,
                        contracts_checksums=self.contracts_checksums,
                        overall_checksum=self.overall_checksum,
                        contracts_version=None,
                    ),
                    sort_keys=True,
                    indent=4,
                ))

        return ContractManager(target_path)
Пример #23
0
def query_blockchain_events(
    web3: Web3,
    contract_manager: ContractManager,
    contract_address: Address,
    contract_name: str,
    topics: List,
    from_block: BlockNumber,
    to_block: BlockNumber,
) -> List[Dict]:
    """Returns events emmitted by a contract for a given event name, within a certain range.

    Args:
        web3: A Web3 instance
        contract_manager: A contract manager
        contract_address: The address of the contract to be filtered, can be `None`
        contract_name: The name of the contract
        topics: The topics to filter for
        from_block: The block to start search events
        to_block: The block to stop searching for events

    Returns:
        All matching events
    """
    events_abi = filter_by_type("event", contract_manager.get_contract_abi(contract_name))
    topic_to_event_abi = {event_abi_to_log_topic(event_abi): event_abi for event_abi in events_abi}

    filter_params = {
        "fromBlock": from_block,
        "toBlock": to_block,
        "address": to_checksum_address(contract_address),
        "topics": topics,
    }

    events = web3.eth.getLogs(filter_params)

    return [decode_event(topic_to_event_abi, log_entry) for log_entry in events]
Пример #24
0
def get_filter_args_for_specific_event_from_channel(
    token_network_address: TokenNetworkAddress,
    channel_identifier: ChannelID,
    event_name: str,
    contract_manager: ContractManager,
    from_block: BlockIdentifier = GENESIS_BLOCK_NUMBER,
    to_block: BlockIdentifier = BLOCK_ID_LATEST,
) -> FilterParams:
    """ Return the filter params for a specific event of a given channel. """
    event_abi = contract_manager.get_event_abi(CONTRACT_TOKEN_NETWORK, event_name)

    # Here the topics for a specific event are created
    # The first entry of the topics list is the event name, then the first parameter is encoded,
    # in the case of a token network, the first parameter is always the channel identifier
    _, event_filter_params = construct_event_filter_params(
        event_abi=event_abi,
        abi_codec=ABI_CODEC,
        contract_address=to_checksum_address(token_network_address),
        argument_filters={"channel_identifier": channel_identifier},
        fromBlock=from_block,
        toBlock=to_block,
    )

    return event_filter_params
Пример #25
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,
    pathfinding_service_address,
    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
    config['services'][
        'pathfinding_service_address'] = pathfinding_service_address

    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
    )

    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
Пример #26
0
def get_token_network(web3: Web3, address: ChecksumAddress,
                      contracts_manager: ContractManager) -> Contract:
    json_contract = contracts_manager.get_contract(CONTRACT_TOKEN_NETWORK)

    return web3.eth.contract(abi=json_contract["abi"], address=address)
Пример #27
0
def contract_manager(contracts_path):
    return ContractManager(contracts_path)
Пример #28
0
    def __init__(
        self,
        account: Account,
        chain_urls: Dict[str, List[str]],
        auth: str,
        data_path: Path,
        scenario_file: Path,
        task_state_callback: Optional[
            Callable[["ScenarioRunner", "Task", "TaskState"], None]
        ] = None,
    ):
        from scenario_player.node_support import RaidenReleaseKeeper, NodeController

        self.auth = auth

        self.release_keeper = RaidenReleaseKeeper(data_path.joinpath("raiden_releases"))

        self.task_count = 0
        self.running_task_count = 0
        self.task_cache = {}
        self.task_state_callback = task_state_callback
        # Storage for arbitrary data tasks might need to persist
        self.task_storage = defaultdict(dict)

        scenario_name = scenario_file.stem
        self.data_path = data_path.joinpath("scenarios", scenario_name)
        self.data_path.mkdir(exist_ok=True, parents=True)
        self.yaml = ScenarioYAML(scenario_file, self.data_path)
        log.debug("Data path", path=self.data_path)

        # Determining the run number requires :attr:`.data_path`
        self.run_number = self.determine_run_number()

        self.node_controller = NodeController(self, self.yaml.nodes)

        self.protocol = "http"

        self.gas_limit = GAS_LIMIT_FOR_TOKEN_CONTRACT_CALL * 2

        self.chain_name, chain_urls = self.select_chain(chain_urls)
        self.eth_rpc_urls = chain_urls
        self.client = JSONRPCClient(
            Web3(HTTPProvider(chain_urls[0])),
            privkey=account.privkey,
            gas_price_strategy=self.yaml.settings.gas_price_strategy,
        )
        self.chain_id = int(self.client.web3.net.version)

        self.contract_manager = ContractManager(contracts_precompiled_path())

        balance = self.client.balance(account.address)
        if balance < OWN_ACCOUNT_BALANCE_MIN:
            raise ScenarioError(
                f"Insufficient balance ({balance / 10 ** 18} Eth) "
                f'in account {to_checksum_address(account.address)} on chain "{self.chain_name}"'
            )

        self.session = Session()
        if auth:
            self.session.auth = tuple(auth.split(":"))
        self.session.mount("http", TimeOutHTTPAdapter(timeout=self.yaml.settings.timeout))
        self.session.mount("https", TimeOutHTTPAdapter(timeout=self.yaml.settings.timeout))

        self.service_session = ServiceInterface(self.yaml.spaas)
        # Request an RPC Client instance ID from the RPC service and assign it to the runner.
        assign_rpc_instance_id(self, chain_urls[0], account.privkey, self.yaml.settings.gas_price)

        self.token = Token(self, data_path)
        self.udc = None

        self.token_network_address = None

        task_config = self.yaml.scenario.root_config
        task_class = self.yaml.scenario.root_class
        self.root_task = task_class(runner=self, config=task_config)
def contract_manager_meta(contracts_path):
    manager = ContractManager(contracts_path)
    abi = manager.get_contract_abi('TokenNetwork')
    assert isinstance(abi, list)
    abi = manager.get_event_abi('TokenNetwork', 'ChannelClosed')
    assert isinstance(abi, dict)
Пример #30
0
def setup_raiden(
    transport,
    matrix_server,
    print_step,
    contracts_version,
    testchain_setup,
):
    print_step('Deploying Raiden contracts')

    client = JSONRPCClient(testchain_setup['web3'],
                           get_private_key(testchain_setup['keystore']))
    contract_manager = ContractManager(
        contracts_precompiled_path(contracts_version), )

    contract_addresses = deploy_smoketest_contracts(
        client=client,
        chain_id=NETWORKNAME_TO_ID['smoketest'],
        contract_manager=contract_manager,
    )
    token = deploy_token(
        deploy_client=client,
        contract_manager=contract_manager,
        initial_amount=1000,
        decimals=0,
        token_name='TKN',
        token_symbol='TKN',
    )
    registry = TokenNetworkRegistry(
        jsonrpc_client=client,
        registry_address=contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY],
        contract_manager=contract_manager,
    )
    registry.add_token(
        token_address=to_canonical_address(token.contract.address),
        given_block_identifier='latest',
    )

    print_step('Setting up Raiden')

    endpoint_registry_contract_address = to_checksum_address(
        contract_addresses[CONTRACT_ENDPOINT_REGISTRY], )
    tokennetwork_registry_contract_address = to_checksum_address(
        contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], )
    secret_registry_contract_address = to_checksum_address(
        contract_addresses[CONTRACT_SECRET_REGISTRY], )
    return {
        'args': {
            'address':
            to_checksum_address(TEST_ACCOUNT_ADDRESS),
            'datadir':
            testchain_setup['keystore'],
            'endpoint_registry_contract_address':
            endpoint_registry_contract_address,
            'eth_rpc_endpoint':
            testchain_setup['eth_rpc_endpoint'],
            'gas_price':
            'fast',
            'keystore_path':
            testchain_setup['keystore'],
            'matrix_server':
            matrix_server,
            'network_id':
            str(NETWORKNAME_TO_ID['smoketest']),
            'password_file':
            click.File()(os.path.join(testchain_setup['base_datadir'], 'pw')),
            'tokennetwork_registry_contract_address':
            tokennetwork_registry_contract_address,
            'secret_registry_contract_address':
            secret_registry_contract_address,
            'sync_check':
            False,
            'transport':
            transport,
        },
        'contract_addresses': contract_addresses,
        'ethereum': testchain_setup['processes_list'],
        'token': token,
    }
def test_verification_overall_checksum():
    """ Tamper with the overall checksum and see failures in verify_precompiled_checksums() """
    manager = ContractManager(contracts_source_path())
    manager.checksum_contracts()
    manager.verify_precompiled_checksums(contracts_precompiled_path())

    original_checksum = manager.overall_checksum

    # We change the source code overall checksum
    manager.overall_checksum += '2'
    # Now the verification should fail
    with pytest.raises(ContractManagerVerificationError):
        manager.verify_precompiled_checksums(contracts_precompiled_path())

    manager.overall_checksum = None
    with pytest.raises(ContractManagerVerificationError):
        manager.verify_precompiled_checksums(contracts_precompiled_path())

    manager.overall_checksum = ''
    with pytest.raises(ContractManagerVerificationError):
        manager.verify_precompiled_checksums(contracts_precompiled_path())

    checksum_fail = list(original_checksum)
    # Replace the first char with a different one
    checksum_fail[0] = list(filter(lambda x: x != checksum_fail[0], ['2', 'a']))[0]
    manager.overall_checksum = "".join(checksum_fail)
    with pytest.raises(ContractManagerVerificationError):
        manager.verify_precompiled_checksums(contracts_precompiled_path())

    manager.overall_checksum = original_checksum
    manager.verify_precompiled_checksums(contracts_precompiled_path())
Пример #32
0
    def __init__(
        self,
        account: Account,
        chain_urls: Dict[str, List[str]],
        auth: str,
        data_path: Path,
        scenario_file: Path,
        task_state_callback: Optional[Callable[
            ["ScenarioRunner", Task, TaskState], None]] = None,
    ):
        from scenario_player.node_support import RaidenReleaseKeeper, NodeController

        self.task_count = 0
        self.running_task_count = 0
        self.auth = auth
        self.release_keeper = RaidenReleaseKeeper(
            data_path.joinpath("raiden_releases"))
        self.task_cache = {}
        self.task_state_callback = task_state_callback
        # Storage for arbitrary data tasks might need to persist
        self.task_storage = defaultdict(dict)

        self.scenario = Scenario(scenario_file)
        self.scenario_name = self.scenario.name

        self.data_path = data_path.joinpath("scenarios", self.scenario.name)
        self.data_path.mkdir(exist_ok=True, parents=True)
        log.debug("Data path", path=self.data_path)

        self.run_number = self.determine_run_number()

        self.node_mode = self.scenario.nodes.mode

        if self.is_managed:
            self.node_controller = NodeController(
                self,
                self.scenario.nodes.raiden_version,
                self.scenario.nodes.count,
                self.scenario.nodes.default_options,
                self.scenario.nodes.node_options,
            )
        else:
            self.raiden_nodes = self.scenario.nodes
            self.node_commands = self.scenario.nodes.commands

        self.timeout = self.scenario.timeout
        self.protocol = self.scenario.protocol

        self.notification_email = self.scenario.notification_email

        self.chain_name, chain_urls = self.select_chain(chain_urls)
        self.eth_rpc_urls = chain_urls

        self.client = JSONRPCClient(
            Web3(HTTPProvider(chain_urls[0])),
            privkey=account.privkey,
            gas_price_strategy=self.scenario.gas_price_strategy,
        )

        self.chain_id = int(self.client.web3.net.version)
        self.contract_manager = ContractManager(contracts_precompiled_path())

        balance = self.client.balance(account.address)
        if balance < OWN_ACCOUNT_BALANCE_MIN:
            raise ScenarioError(
                f"Insufficient balance ({balance / 10 ** 18} Eth) "
                f'in account {to_checksum_address(account.address)} on chain "{self.chain_name}"'
            )

        self.session = Session()
        if auth:
            self.session.auth = tuple(auth.split(":"))
        self.session.mount("http", TimeOutHTTPAdapter(timeout=self.timeout))
        self.session.mount("https", TimeOutHTTPAdapter(timeout=self.timeout))

        self._node_to_address = None
        self.token_address = None
        self.token_deployment_block = 0
        self.token_network_address = None

        task_config = self.scenario.task_config
        task_class = self.scenario.task_class
        self.root_task = task_class(runner=self, config=task_config)
Пример #33
0
 def abi(contract_manager: ContractManager) -> ABI:
     """Overwrittable by subclasses to change the proxies ABI."""
     return contract_manager.get_contract_abi(CONTRACT_CUSTOM_TOKEN)
Пример #34
0
def main(output_directory, network_id, eth_rpc_endpoint, contracts_version):
    web3 = Web3(HTTPProvider(rpc_normalized_endpoint(eth_rpc_endpoint)))

    try:
        check_ethereum_client_is_supported(web3)
    except ConnectionError:
        click.secho(
            f"Couldn't connect to the ethereum node, double check it is running "
            f"on {eth_rpc_endpoint}, this option can be changed with "
            f"{ETH_RPC_CONFIG_OPTION}",
            fg="red",
        )
        return

    check_ethereum_network_id(network_id, web3)

    # This script does not send any transactions, the privatekey is generate
    # just because it is a dependency for JSONRPCClient.
    unecessary_privatekey = factories.make_privatekey_bin()
    rpc_client = JSONRPCClient(web3=web3, privkey=unecessary_privatekey)
    check_synced(rpc_client)

    deployment_data = get_contracts_deployment_info(chain_id=network_id, version=contracts_version)

    if not deployment_data:
        raise RuntimeError(
            f"There is no deployment data available for contracts-version {contracts_version}."
        )

    network_name = ID_TO_CHAINNAME.get(network_id)
    if network_name is None:
        raise RuntimeError(f"Network with id {network_id} is not known.")

    contracts = deployment_data["contracts"]
    token_network_registry_deployed_at = BlockNumber(
        contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]["block_number"]
    )
    token_network_registry_address = TokenNetworkRegistryAddress(
        to_canonical_address(contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]["address"])
    )
    secret_registry_address = SecretRegistryAddress(
        to_canonical_address(contracts[CONTRACT_SECRET_REGISTRY]["address"])
    )

    contracts_path = contracts_precompiled_path(contracts_version)
    contract_manager = ContractManager(contracts_path)

    current_block_number = rpc_client.block_number()
    confirmed_block = rpc_client.get_block(
        BlockNumber(current_block_number - DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS)
    )

    all_events_for_a_deployment = fetch_all_events_for_a_deployment(
        contract_manager=contract_manager,
        web3=web3,
        token_network_registry_address=token_network_registry_address,
        secret_registry_address=secret_registry_address,
        start_block=token_network_registry_deployed_at,
        target_block=confirmed_block["number"],
    )

    target_block_formatted = to_hex(confirmed_block["hash"])
    file_path = os.path.join(
        output_directory,
        (
            f"{network_name}-"
            f"{to_checksum_address(token_network_registry_address)}-"
            f"{target_block_formatted}.json.gz"
        ),
    )

    block_data = {
        "gasLimit": confirmed_block["gasLimit"],
        "gasUsed": confirmed_block["gasUsed"],
        "hash": to_hex(confirmed_block["hash"]),
        "number": confirmed_block["number"],
    }
    block_data_formatted = simplejson.dumps(block_data).encode("utf8")

    with gzip.open(file_path, mode="wb") as handler:
        # Format is `jsonlines` (http://jsonlines.org/), this is used because we
        # don't have to keep all the events in memory to start encoding the data.
        for event in all_events_for_a_deployment:
            format_event_for_serialization(event)
            data = simplejson.dumps(event).encode("utf8")
            handler.write(data + b"\n")

        # Write the block details at the end
        handler.write(block_data_formatted + b"\n")
def test_contracts_version():
    """ Check the value of contracts_version """
    manager = ContractManager(contracts_precompiled_path())
    assert manager.contracts_version == CONTRACTS_VERSION
def test_verification_contracts_checksums():
    """ Tamper with the contract checksums and see failures in verify_precompiled_checksums() """
    manager = ContractManager(contracts_source_path())
    manager.checksum_contracts()
    manager.verify_precompiled_checksums(contracts_precompiled_path())

    for contract, checksum in manager.contracts_checksums.items():
        manager.contracts_checksums[contract] += '2'
        with pytest.raises(ContractManagerVerificationError):
            manager.verify_precompiled_checksums(contracts_precompiled_path())

        manager.contracts_checksums[contract] = None
        with pytest.raises(ContractManagerVerificationError):
            manager.verify_precompiled_checksums(contracts_precompiled_path())

        manager.contracts_checksums[contract] = ''
        with pytest.raises(ContractManagerVerificationError):
            manager.verify_precompiled_checksums(contracts_precompiled_path())

        checksum_fail = list(checksum)
        # Replace the first char with a different one
        checksum_fail[0] = list(filter(lambda x: x != checksum_fail[0], ['2', 'a']))[0]
        manager.contracts_checksums[contract] = "".join(checksum_fail)
        with pytest.raises(ContractManagerVerificationError):
            manager.verify_precompiled_checksums(contracts_precompiled_path())

        manager.contracts_checksums[contract] = checksum
        manager.verify_precompiled_checksums(contracts_precompiled_path())
Пример #37
0
    def __init__(
        self,
        web3: Web3,
        contract_manager: ContractManager,
        private_key: str,
        state_db: StateDBSqlite,
        registry_address: Address,
        monitor_contract_address: Address,
        sync_start_block: int = 0,
        required_confirmations: int = 8,
        poll_interval: int = 10,
    ):
        super().__init__()

        assert isinstance(private_key, str)
        assert is_checksum_address(private_key_to_address(private_key))

        self.web3 = web3
        self.contract_manager = contract_manager
        self.private_key = private_key
        self.state_db = state_db
        self.stop_event = gevent.event.Event()
        self.address = private_key_to_address(self.private_key)
        self.monitor_contract = PrivateContract(
            self.web3.eth.contract(
                abi=contract_manager.get_contract_abi(CONTRACT_MONITORING_SERVICE),
                address=monitor_contract_address,
            ),
        )

        self.token_network_listener = TokenNetworkListener(
            web3,
            contract_manager,
            registry_address,
            required_confirmations,
            poll_interval,
            load_syncstate=state_db.load_syncstate,
            save_syncstate=state_db.save_syncstate,
            get_synced_contracts=state_db.get_synced_contracts,
        )
        self.token_network_listener.add_confirmed_channel_event_listener(
            self.on_channel_event,
        )

        # some sanity checks
        chain_id = int(self.web3.version.network)
        if state_db.is_initialized() is False:
            state_db.setup_db(chain_id, monitor_contract_address, self.address)
        if state_db.chain_id() != chain_id:
            raise StateDBInvalid("Chain id doesn't match!")
        if not is_same_address(state_db.server_address(), self.address):
            raise StateDBInvalid("Monitor service address doesn't match!")
        if not is_same_address(state_db.monitoring_contract_address(), monitor_contract_address):
            raise StateDBInvalid("Monitoring contract address doesn't match!")
        self.task_list: List[gevent.Greenlet] = []
        if not is_service_registered(
            self.web3,
            contract_manager,
            monitor_contract_address,
            self.address,
        ):
            raise ServiceNotRegistered(
                "Monitoring service %s is not registered in the Monitoring smart contract (%s)" %
                (self.address, monitor_contract_address),
            )
Пример #38
0
def contract_manager(environment_type):
    version = None
    if environment_type == Environment.DEVELOPMENT:
        version = 'pre_limits'

    return ContractManager(contracts_precompiled_path(version))
Пример #39
0
def run_app(
    address,
    keystore_path,
    gas_price,
    eth_rpc_endpoint,
    tokennetwork_registry_contract_address,
    secret_registry_contract_address,
    service_registry_contract_address,
    endpoint_registry_contract_address,
    user_deposit_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,
    pathfinding_service_address,
    pathfinding_eth_address,
    pathfinding_max_paths,
    enable_monitoring,
    resolver_endpoint,
    routing_mode,
    config=None,
    extra_config=None,
    **kwargs,
):
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements,unused-argument

    from raiden.app import App

    check_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")

    account_manager = AccountManager(keystore_path)
    check_has_accounts(account_manager)

    if not address:
        address_hex = prompt_account(account_manager)
    else:
        address_hex = to_normalized_address(address)

    if password_file:
        privatekey_bin = unlock_account_with_passwordfile(
            account_manager=account_manager,
            address_hex=address_hex,
            password_file=password_file)
    else:
        privatekey_bin = unlock_account_with_passwordprompt(
            account_manager=account_manager, address_hex=address_hex)

    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
    config["resolver_endpoint"] = resolver_endpoint
    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[
        "unrecoverable_error_should_crash"] = unrecoverable_error_should_crash
    config["services"]["pathfinding_max_paths"] = pathfinding_max_paths
    config["services"]["monitoring_enabled"] = enable_monitoring

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

    web3 = Web3(HTTPProvider(eth_rpc_endpoint))
    check_ethereum_version(web3)
    check_network_id(network_id, web3)
    config["chain_id"] = network_id

    setup_environment(config, environment_type)

    contracts = setup_contracts_or_exit(config, network_id)

    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(jsonrpc_client=rpc_client,
                                           contract_manager=ContractManager(
                                               config["contracts_path"]))

    if sync_check:
        check_synced(blockchain_service)

    proxies = setup_proxies_or_exit(
        config=config,
        tokennetwork_registry_contract_address=
        tokennetwork_registry_contract_address,
        secret_registry_contract_address=secret_registry_contract_address,
        endpoint_registry_contract_address=endpoint_registry_contract_address,
        user_deposit_contract_address=user_deposit_contract_address,
        service_registry_contract_address=service_registry_contract_address,
        blockchain_service=blockchain_service,
        contracts=contracts,
        routing_mode=routing_mode,
        pathfinding_service_address=pathfinding_service_address,
        pathfinding_eth_address=pathfinding_eth_address,
    )

    database_path = os.path.join(
        datadir,
        f"node_{pex(address)}",
        f"netid_{network_id}",
        f"network_{pex(proxies.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(network_id, network_id), database_path))

    discovery = None
    if transport == "udp":
        transport, discovery = setup_udp_or_exit(
            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:
        start_block = 0
        if "TokenNetworkRegistry" in contracts:
            start_block = contracts["TokenNetworkRegistry"]["block_number"]

        raiden_app = App(
            config=config,
            chain=blockchain_service,
            query_start_block=start_block,
            default_registry=proxies.token_network_registry,
            default_secret_registry=proxies.secret_registry,
            default_service_registry=proxies.service_registry,
            transport=transport,
            raiden_event_handler=raiden_event_handler,
            message_handler=message_handler,
            discovery=discovery,
            user_deposit=proxies.user_deposit,
        )
    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(network_id, 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_contract_manager_json(tmpdir):
    """ Check the ABI in contracts.json """
    precompiled_path = Path(str(tmpdir)).joinpath('contracts.json')
    ContractManager(contracts_source_path()).compile_contracts(precompiled_path)
    # try to load contracts from a precompiled file
    contract_manager_meta(precompiled_path)