Example #1
0
def deploy_monitoring_service(
    token_deploy_result: Callable[[], Contract],
    user_deposit_deploy_result: Callable[[], UserDeposit],
    service_registry_deploy_result: Callable[[], ServiceRegistry],
    token_network_registry_deploy_result: Callable[[], TokenNetworkRegistry],
    deploy_client: JSONRPCClient,
    contract_manager: ContractManager,
    proxy_manager: ProxyManager,
) -> MonitoringService:
    token_contract = token_deploy_result()
    token_network_registry_proxy = token_network_registry_deploy_result()
    user_deposit_proxy = user_deposit_deploy_result()
    service_registry_proxy = service_registry_deploy_result()
    contract, receipt = deploy_client.deploy_single_contract(
        contract_name=CONTRACT_MONITORING_SERVICE,
        contract=contract_manager.get_contract(CONTRACT_MONITORING_SERVICE),
        constructor_parameters=[
            token_contract.address,
            service_registry_proxy.address,
            user_deposit_proxy.address,
            token_network_registry_proxy.address,
        ],
    )
    return proxy_manager.monitoring_service(
        MonitoringServiceAddress(to_canonical_address(contract.address)),
        BlockNumber(receipt["blockNumber"]),
    )
Example #2
0
 def monitoring_service_address(
         self,
         block_identifier: BlockSpecification) -> MonitoringServiceAddress:
     return MonitoringServiceAddress(
         to_canonical_address(
             self.proxy.contract.functions.msc_address().call(
                 block_identifier=block_identifier)))
Example #3
0
    def __init__(  # pylint: disable=too-many-arguments
        self,
        web3: Web3,
        private_key: PrivateKey,
        db_filename: str,
        contracts: Dict[str, Contract],
        sync_start_block: BlockNumber,
        required_confirmations: BlockTimeout,
        poll_interval: float,
        min_reward: int = 0,
    ):
        self.web3 = web3
        self.chain_id = ChainID(web3.eth.chainId)
        self.private_key = private_key
        self.address = private_key_to_address(private_key)
        self.poll_interval = poll_interval
        self.service_registry = contracts[CONTRACT_SERVICE_REGISTRY]
        self.token_network_registry = contracts[
            CONTRACT_TOKEN_NETWORK_REGISTRY]

        web3.middleware_onion.add(
            construct_sign_and_send_raw_middleware(private_key))

        monitoring_contract = contracts[CONTRACT_MONITORING_SERVICE]
        user_deposit_contract = contracts[CONTRACT_USER_DEPOSIT]

        self.database = Database(
            filename=db_filename,
            chain_id=self.chain_id,
            registry_address=to_canonical_address(
                self.token_network_registry.address),
            receiver=self.address,
            msc_address=MonitoringServiceAddress(
                to_canonical_address(monitoring_contract.address)),
            sync_start_block=sync_start_block,
        )
        ms_state = self.database.load_state()

        self.context = Context(
            ms_state=ms_state,
            database=self.database,
            web3=self.web3,
            monitoring_service_contract=monitoring_contract,
            user_deposit_contract=user_deposit_contract,
            min_reward=min_reward,
            required_confirmations=required_confirmations,
        )
Example #4
0
def load_deployment_addresses_from_contracts(
        contracts: Dict[str, Any]) -> DeploymentAddresses:
    return DeploymentAddresses(
        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"])),
        user_deposit_address=UserDepositAddress(
            to_canonical_address(contracts[CONTRACT_USER_DEPOSIT]["address"])),
        service_registry_address=ServiceRegistryAddress(
            to_canonical_address(
                contracts[CONTRACT_SERVICE_REGISTRY]["address"])),
        monitoring_service_address=MonitoringServiceAddress(
            to_canonical_address(
                contracts[CONTRACT_MONITORING_SERVICE]["address"])),
        one_to_n_address=OneToNAddress(
            to_canonical_address(contracts[CONTRACT_ONE_TO_N]["address"])),
    )
def request_monitoring_message(token_network, get_accounts, get_private_key) -> RequestMonitoring:
    c1, c2 = get_accounts(2)

    balance_proof_c2 = HashedBalanceProof(
        channel_identifier=ChannelID(1),
        token_network_address=TokenNetworkAddress(to_canonical_address(token_network.address)),
        chain_id=ChainID(61),
        nonce=Nonce(2),
        additional_hash="0x%064x" % 0,
        transferred_amount=TokenAmount(1),
        locked_amount=TokenAmount(0),
        locksroot=encode_hex(LOCKSROOT_OF_NO_LOCKS),
        priv_key=get_private_key(c2),
    )

    return balance_proof_c2.get_request_monitoring(
        privkey=get_private_key(c1),
        reward_amount=TokenAmount(1),
        monitoring_service_contract_address=MonitoringServiceAddress(bytes([11] * 20)),
    )
Example #6
0
from eth_utils import keccak

from raiden.constants import EMPTY_SIGNATURE, UINT64_MAX, UINT256_MAX
from raiden.messages.healthcheck import Ping
from raiden.messages.monitoring_service import RequestMonitoring, SignedBlindedBalanceProof
from raiden.messages.path_finding_service import PFSCapacityUpdate, PFSFeeUpdate
from raiden.storage.serialization import DictSerializer
from raiden.tests.utils import factories
from raiden.tests.utils.tests import fixture_all_combinations
from raiden.transfer.mediated_transfer.mediation_fee import FeeScheduleState
from raiden.utils.packing import pack_balance_proof, pack_reward_proof, pack_signed_balance_proof
from raiden.utils.signer import LocalSigner, recover
from raiden.utils.typing import MonitoringServiceAddress, TokenAmount
from raiden_contracts.constants import MessageTypeId

MSC_ADDRESS = MonitoringServiceAddress(bytes([1] * 20))
PARTNER_PRIVKEY, PARTNER_ADDRESS = factories.make_privkey_address()
PRIVKEY, ADDRESS = factories.make_privkey_address()
signer = LocalSigner(PRIVKEY)


def test_signature():
    ping = Ping(nonce=0, current_protocol_version=0, signature=EMPTY_SIGNATURE)
    ping.sign(signer)
    assert ping.sender == ADDRESS


def test_request_monitoring() -> None:
    properties = factories.BalanceProofSignedStateProperties(
        pkey=PARTNER_PRIVKEY)
    balance_proof = factories.create(properties)
Example #7
0
from raiden.utils.typing import MonitoringServiceAddress

KEYSTORE_FILE_NAME = "keystore.txt"
KEYSTORE_PASSWORD = "******"
TEST_MSC_ADDRESS = MonitoringServiceAddress(b"9" * 20)
def test_first_allowed_monitoring(
    web3: Web3,
    monitoring_service_contract,
    wait_for_blocks,
    service_registry,
    monitoring_service: MonitoringService,
    request_collector: RequestCollector,
    deposit_to_udc,
    create_channel,
    token_network,
    get_accounts,
    get_private_key,
):
    # pylint: disable=too-many-arguments,too-many-locals,protected-access
    query = create_ms_contract_events_query(web3, monitoring_service_contract.address)
    c1, c2 = get_accounts(2)

    # add deposit for c1
    node_deposit = 10
    deposit_to_udc(c1, node_deposit)

    assert service_registry.functions.hasValidRegistration(monitoring_service.address).call()

    # each client does a transfer
    channel_id = create_channel(c1, c2, settle_timeout=10)[0]

    shared_bp_args = dict(
        channel_identifier=channel_id,
        token_network_address=decode_hex(token_network.address),
        chain_id=monitoring_service.chain_id,
        additional_hash="0x%064x" % 0,
        locked_amount=TokenAmount(0),
        locksroot=encode_hex(LOCKSROOT_OF_NO_LOCKS),
    )
    transferred_c1 = 5
    balance_proof_c1 = HashedBalanceProof(
        nonce=Nonce(1),
        transferred_amount=transferred_c1,
        priv_key=get_private_key(c1),
        **shared_bp_args,
    )
    transferred_c2 = 6
    balance_proof_c2 = HashedBalanceProof(
        nonce=Nonce(2),
        transferred_amount=transferred_c2,
        priv_key=get_private_key(c2),
        **shared_bp_args,
    )
    monitoring_service._process_new_blocks(web3.eth.blockNumber)
    assert len(monitoring_service.context.database.get_token_network_addresses()) > 0

    # c1 asks MS to monitor the channel
    reward_amount = TokenAmount(1)
    request_monitoring = balance_proof_c2.get_request_monitoring(
        privkey=get_private_key(c1),
        reward_amount=reward_amount,
        monitoring_service_contract_address=MonitoringServiceAddress(
            to_canonical_address(monitoring_service_contract.address)
        ),
    )
    request_collector.on_monitor_request(request_monitoring)

    # c2 closes the channel
    token_network.functions.closeChannel(
        channel_id,
        c1,
        c2,
        balance_proof_c1.balance_hash,
        balance_proof_c1.nonce,
        balance_proof_c1.additional_hash,
        balance_proof_c1.signature,
        balance_proof_c1.get_counter_signature(get_private_key(c2)),
    ).transact({"from": c2})

    monitoring_service._process_new_blocks(web3.eth.blockNumber)
    triggered_events = monitoring_service.database.get_scheduled_events(
        max_trigger_block=BlockNumber(web3.eth.blockNumber + 10)
    )
    assert len(triggered_events) == 1

    monitor_trigger = triggered_events[0]
    channel = monitoring_service.database.get_channel(
        token_network_address=TokenNetworkAddress(to_canonical_address(token_network.address)),
        channel_id=channel_id,
    )
    assert channel

    # Calling monitor too early must fail. To test this, we call it two block
    # before the trigger block.
    # This should be only one block before, but we trigger one block too late
    # to work around parity's gas estimation. See
    # https://github.com/raiden-network/raiden-services/pull/728
    wait_for_blocks(monitor_trigger.trigger_block_number - web3.eth.blockNumber - 2)
    handle_event(monitor_trigger.event, monitoring_service.context)
    assert [e.event for e in query()] == []

    # If our `monitor` call fails, we won't try again. Force a retry in this
    # test by clearing monitor_tx_hash.
    channel.monitor_tx_hash = None
    monitoring_service.database.upsert_channel(channel)

    # Now we can try again. The first try mined a new block, so now we're one
    # block further and `monitor` should succeed.
    handle_event(monitor_trigger.event, monitoring_service.context)
    assert [e.event for e in query()] == [MonitoringServiceEvent.NEW_BALANCE_PROOF_RECEIVED]
def test_e2e(  # pylint: disable=too-many-arguments,too-many-locals
    web3,
    monitoring_service_contract,
    user_deposit_contract,
    wait_for_blocks,
    service_registry,
    monitoring_service: MonitoringService,
    request_collector: RequestCollector,
    deposit_to_udc,
    create_channel,
    token_network,
    get_accounts,
    get_private_key,
):
    """Test complete message lifecycle
    1) client opens channel & submits monitoring request
    2) other client closes channel
    3) MS registers channelClose event
    4) MS calls monitoring contract update
    5) wait for channel settle
    6) MS claims the reward
    """
    query = create_ms_contract_events_query(web3, monitoring_service_contract.address)
    initial_balance = user_deposit_contract.functions.balances(monitoring_service.address).call()
    c1, c2 = get_accounts(2)

    # add deposit for c1
    node_deposit = 10
    deposit_to_udc(c1, node_deposit)

    assert service_registry.functions.hasValidRegistration(monitoring_service.address).call()

    # each client does a transfer
    channel_id = create_channel(c1, c2, settle_timeout=5)[0]

    shared_bp_args = dict(
        channel_identifier=channel_id,
        token_network_address=decode_hex(token_network.address),
        chain_id=monitoring_service.chain_id,
        additional_hash="0x%064x" % 0,
        locked_amount=TokenAmount(0),
        locksroot=encode_hex(LOCKSROOT_OF_NO_LOCKS),
    )
    transferred_c1 = 5
    balance_proof_c1 = HashedBalanceProof(
        nonce=Nonce(1),
        transferred_amount=transferred_c1,
        priv_key=get_private_key(c1),
        **shared_bp_args,
    )
    transferred_c2 = 6
    balance_proof_c2 = HashedBalanceProof(
        nonce=Nonce(2),
        transferred_amount=transferred_c2,
        priv_key=get_private_key(c2),
        **shared_bp_args,
    )

    ms_greenlet = gevent.spawn(monitoring_service.start)

    # need to wait here till the MS has some time to react
    gevent.sleep(0.01)
    assert len(monitoring_service.context.database.get_token_network_addresses()) > 0

    # c1 asks MS to monitor the channel
    reward_amount = TokenAmount(1)
    request_monitoring = balance_proof_c2.get_request_monitoring(
        privkey=get_private_key(c1),
        reward_amount=reward_amount,
        monitoring_service_contract_address=MonitoringServiceAddress(
            to_canonical_address(monitoring_service_contract.address)
        ),
    )
    request_collector.on_monitor_request(request_monitoring)

    # c2 closes the channel
    token_network.functions.closeChannel(
        channel_id,
        c1,
        c2,
        balance_proof_c1.balance_hash,
        balance_proof_c1.nonce,
        balance_proof_c1.additional_hash,
        balance_proof_c1.signature,
        balance_proof_c1.get_counter_signature(get_private_key(c2)),
    ).transact({"from": c2})
    # Wait until the MS reacts, which it does after giving the client some time
    # to update the channel itself.

    wait_for_blocks(2)  # 1 block for close + 1 block for triggering the event
    # Now give the monitoring service a chance to submit the missing BP
    gevent.sleep(0.01)
    assert [e.event for e in query()] == [MonitoringServiceEvent.NEW_BALANCE_PROOF_RECEIVED]

    # wait for settle timeout
    # timeout is 5, but we've already waited 3 blocks before. Additionally one block is
    # added to handle parity running gas estimation on current instead of next.
    wait_for_blocks(3)

    # Let the MS claim its reward
    gevent.sleep(0.01)
    assert [e.event for e in query()] == [
        MonitoringServiceEvent.NEW_BALANCE_PROOF_RECEIVED,
        MonitoringServiceEvent.REWARD_CLAIMED,
    ]

    final_balance = user_deposit_contract.functions.balances(monitoring_service.address).call()
    assert final_balance == (initial_balance + reward_amount)

    ms_greenlet.kill()
Example #10
0
def deploy_smoketest_contracts(
    client: JSONRPCClient,
    chain_id: ChainID,
    contract_manager: ContractManager,
    token_address: AddressHex,
) -> Dict[str, Address]:
    if client.eth_node is EthClient.GETH:
        client.web3.geth.personal.unlockAccount(client.web3.eth.accounts[0],
                                                DEFAULT_PASSPHRASE)
    elif client.eth_node is EthClient.PARITY:
        client.web3.parity.personal.unlockAccount(client.web3.eth.accounts[0],
                                                  DEFAULT_PASSPHRASE)

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

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

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

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

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

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

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

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

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

    return addresses
Example #11
0
def deploy_smoketest_contracts(
    client: JSONRPCClient,
    proxy_manager: ProxyManager,
    chain_id: ChainID,
    contract_manager: ContractManager,
    token_address: AddressHex,
) -> Dict[str, Address]:
    client.web3.personal.unlockAccount(client.web3.eth.accounts[0], DEFAULT_PASSPHRASE)

    secret_registry_address = deploy_contract_web3(
        contract_name=CONTRACT_SECRET_REGISTRY,
        deploy_client=client,
        contract_manager=contract_manager,
    )
    constructor_arguments = [
        to_checksum_address(secret_registry_address),
        chain_id,
        TEST_SETTLE_TIMEOUT_MIN,
        TEST_SETTLE_TIMEOUT_MAX,
        UINT256_MAX,
    ]

    token_network_registry_address = deploy_contract_web3(
        contract_name=CONTRACT_TOKEN_NETWORK_REGISTRY,
        deploy_client=client,
        contract_manager=contract_manager,
        constructor_arguments=constructor_arguments,
    )

    addresses = {
        CONTRACT_SECRET_REGISTRY: secret_registry_address,
        CONTRACT_TOKEN_NETWORK_REGISTRY: token_network_registry_address,
    }
    service_registry_address = deploy_contract_web3(
        contract_name=CONTRACT_SERVICE_REGISTRY,
        deploy_client=client,
        contract_manager=contract_manager,
        constructor_arguments=(
            token_address,
            EMPTY_ADDRESS,
            int(500e18),
            6,
            5,
            180 * SECONDS_PER_DAY,
            1000,
            200 * SECONDS_PER_DAY,
        ),
    )
    addresses[CONTRACT_SERVICE_REGISTRY] = service_registry_address

    user_deposit_address = deploy_contract_web3(
        contract_name=CONTRACT_USER_DEPOSIT,
        deploy_client=client,
        contract_manager=contract_manager,
        constructor_arguments=(token_address, UINT256_MAX),
    )
    addresses[CONTRACT_USER_DEPOSIT] = user_deposit_address

    monitoring_service_address = deploy_contract_web3(
        contract_name=CONTRACT_MONITORING_SERVICE,
        deploy_client=client,
        contract_manager=contract_manager,
        constructor_arguments=(
            token_address,
            service_registry_address,
            user_deposit_address,
            token_network_registry_address,
        ),
    )
    addresses[CONTRACT_MONITORING_SERVICE] = monitoring_service_address

    one_to_n_address = deploy_contract_web3(
        contract_name=CONTRACT_ONE_TO_N,
        deploy_client=client,
        contract_manager=contract_manager,
        constructor_arguments=(user_deposit_address, chain_id, service_registry_address),
    )
    addresses[CONTRACT_ONE_TO_N] = one_to_n_address

    user_deposit_proxy = proxy_manager.user_deposit(UserDepositAddress(user_deposit_address))
    user_deposit_proxy.init(
        monitoring_service_address=MonitoringServiceAddress(monitoring_service_address),
        one_to_n_address=OneToNAddress(one_to_n_address),
        given_block_identifier="latest",
    )

    return addresses