Ejemplo n.º 1
0
def test_mediated_transfer(iterations=ITERATIONS):
    identifier = 1
    amount = 1
    expiration = 1
    secrethash = sha3(ADDRESS)
    lock = Lock(amount, expiration, secrethash)

    nonce = 1
    token = ADDRESS
    balance = 1
    recipient = ADDRESS
    locksroot = sha3(ADDRESS)
    target = ADDRESS
    initiator = ADDRESS
    msg = LockedTransfer(
        identifier,
        nonce,
        token,
        balance,
        recipient,
        locksroot,
        lock,
        target,
        initiator,
        fee=0,
    )
    msg.sign(PRIVKEY, ADDRESS)

    run_timeit('MediatedTranfer', msg, iterations=iterations)
Ejemplo n.º 2
0
def test_receive_hashlocktransfer_unknown(raiden_network):
    app0 = raiden_network[0]  # pylint: disable=unbalanced-tuple-unpacking

    token_manager0 = app0.raiden.managers_by_token_address.values()[0]

    other_key = PrivateKey(HASH2, ctx=GLOBAL_CTX, raw=True)
    other_address = privatekey_to_address(other_key.private_key)
    amount = 10
    lock = Lock(amount, 1, HASH)
    refund_transfer = RefundTransfer(identifier=1,
                                     nonce=1,
                                     token=token_manager0.token_address,
                                     transferred_amount=amount,
                                     recipient=app0.raiden.address,
                                     locksroot=HASH,
                                     lock=lock)
    sign_and_send(refund_transfer, other_key, other_address, app0)

    transfer_timeout = TransferTimeout(HASH, HASH)
    sign_and_send(transfer_timeout, other_key, other_address, app0)

    secret = Secret(1, HASH, token_manager0.token_address)
    sign_and_send(secret, other_key, other_address, app0)

    secret_request = SecretRequest(1, HASH, 1)
    sign_and_send(secret_request, other_key, other_address, app0)

    reveal_secret = RevealSecret(HASH)
    sign_and_send(reveal_secret, other_key, other_address, app0)

    # Whenever processing of ConfirmTransfer is implemented test it here
    # too by removing the expectation of an exception
    with pytest.raises(KeyError):
        confirm_transfer = ConfirmTransfer(HASH)
        sign_and_send(confirm_transfer, other_key, other_address, app0)
Ejemplo n.º 3
0
def _(properties, defaults=None) -> LockedTransferSignedState:
    defaults = defaults or LOCKED_TRANSFER_SIGNED_STATE_DEFAULTS
    params = _properties_to_dict(properties, defaults)

    transfer_params = _properties_to_dict(params.pop('transfer'),
                                          defaults.transfer)
    balance_proof_params = _properties_to_dict(
        transfer_params.pop('balance_proof'),
        defaults.transfer.balance_proof,
    )

    lock = Lock(
        amount=transfer_params.pop('amount'),
        expiration=transfer_params.pop('expiration'),
        secrethash=sha3(transfer_params.pop('secret')),
    )

    pkey = params.pop('pkey')
    signer = LocalSigner(pkey)
    sender = params.pop('sender')
    params.update(transfer_params)
    params.update(balance_proof_params)
    params['token_network_address'] = params.pop('token_network_identifier')
    if params['locksroot'] == EMPTY_MERKLE_ROOT:
        params['locksroot'] = lock.lockhash

    locked_transfer = LockedTransfer(lock=lock, **params)
    locked_transfer.sign(signer)

    assert locked_transfer.sender == sender

    return lockedtransfersigned_from_message(locked_transfer)
Ejemplo n.º 4
0
def test_mediated_transfer(iterations=ITERATIONS):
    amount = 1
    expiration = 1
    hashlock = sha3(ADDRESS)
    lock = Lock(amount, expiration, hashlock)

    nonce = 1
    asset = ADDRESS
    balance = 1
    recipient = ADDRESS
    locksroot = sha3(ADDRESS)
    target = ADDRESS
    initiator = ADDRESS
    msg = MediatedTransfer(nonce,
                           asset,
                           balance,
                           recipient,
                           locksroot,
                           lock,
                           target,
                           initiator,
                           fee=0)
    msg.sign(PRIVKEY)

    run_timeit('MediatedTranfer', msg, iterations=iterations)
Ejemplo n.º 5
0
    def unlock(self, ctx, locked_encoded, merkleproof_encoded, secret):
        if self.settled is not 0:
            raise RuntimeError('Contract is settled.')

        if self.closed is 0:
            raise RuntimeError('Contract is open.')

        if ctx['msg.sender'] not in self.participants:
            raise ValueError('Unknow address.')

        partner = self.partner(ctx['msg.sender'])
        state = self.participants[partner]
        transfer = state.transfer

        # if partner haven't made a single transfer
        if transfer is None:
            return

        merkle_proof = tuple32(merkleproof_encoded)
        lock = Lock.from_bytes(locked_encoded)

        hashlock = lock.hashlock
        if hashlock != sha3(secret):
            raise ValueError('Invalid secret')

        is_valid_proof = check_proof(
            merkle_proof,
            transfer.locksroot,
            sha3(lock.as_bytes),
        )

        if not is_valid_proof:
            raise ValueError('Invalid merkle proof')

        transfer.append(lock)
Ejemplo n.º 6
0
def test_receive_hashlocktransfer_unknown(raiden_network):
    app0 = raiden_network[0]  # pylint: disable=unbalanced-tuple-unpacking

    token_manager0 = app0.raiden.managers_by_token_address.values()[0]

    other_key = PrivateKey(HASH2, ctx=GLOBAL_CTX, raw=True)
    other_address = privatekey_to_address(other_key.private_key)
    amount = 10
    lock = Lock(amount, 1, HASH)
    refund_transfer = RefundTransfer(identifier=1,
                                     nonce=1,
                                     token=token_manager0.token_address,
                                     transferred_amount=amount,
                                     recipient=app0.raiden.address,
                                     locksroot=HASH,
                                     lock=lock)
    sign_and_send(refund_transfer, other_key, other_address, app0)

    secret = Secret(1, HASH, token_manager0.token_address)
    sign_and_send(secret, other_key, other_address, app0)

    secret_request = SecretRequest(1, HASH, 1)
    sign_and_send(secret_request, other_key, other_address, app0)

    reveal_secret = RevealSecret(HASH)
    sign_and_send(reveal_secret, other_key, other_address, app0)
Ejemplo n.º 7
0
def test_withdraw_twice(tester_registry_address, reveal_timeout, tester_channels, tester_chain):
    """ A lock can be withdrawn only once, the second try must fail. """
    pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0]
    pseudo_random_generator = random.Random()

    lock_expiration = tester_chain.block.number + reveal_timeout + 5
    secret = b'secretsecretsecretsecretsecretse'
    new_block = Block(tester_chain.block.number)
    channel.state_transition(
        channel0,
        new_block,
        pseudo_random_generator,
        new_block.block_number,
    )
    channel.state_transition(
        channel1,
        new_block,
        pseudo_random_generator,
        new_block.block_number,
    )
    lock = Lock(17, lock_expiration, sha3(secret))

    mediated0 = make_mediated_transfer(
        tester_registry_address,
        channel1,
        channel0,
        privatekey_to_address(pkey1),
        privatekey_to_address(pkey0),
        lock,
        pkey1,
        secret,
    )

    mediated0_hash = sha3(mediated0.packed().data[:-65])
    nettingchannel.close(
        mediated0.nonce,
        mediated0.transferred_amount,
        mediated0.locksroot,
        mediated0_hash,
        mediated0.signature,
        sender=pkey0,
    )

    unlock_proofs = channel.get_known_unlocks(channel0.partner_state)
    proof = unlock_proofs[0]

    nettingchannel.withdraw(
        proof.lock_encoded,
        b''.join(proof.merkle_proof),
        proof.secret,
        sender=pkey0,
    )

    with pytest.raises(TransactionFailed):
        nettingchannel.withdraw(
            proof.lock_encoded,
            b''.join(proof.merkle_proof),
            proof.secret,
            sender=pkey0,
        )
Ejemplo n.º 8
0
def make_signed_transfer_from_counter(counter):
    lock = Lock(
        amount=next(counter),
        expiration=next(counter),
        secrethash=sha3(factories.make_secret(next(counter))),
    )

    signed_transfer = factories.make_signed_transfer_state(
        amount=next(counter),
        initiator=factories.make_address(),
        target=factories.make_address(),
        expiration=next(counter),
        secret=factories.make_secret(next(counter)),
        payment_identifier=next(counter),
        message_identifier=next(counter),
        nonce=next(counter),
        transferred_amount=next(counter),
        locked_amount=next(counter),
        locksroot=sha3(lock.as_bytes),
        recipient=factories.make_address(),
        channel_identifier=next(counter),
        token_network_address=factories.make_address(),
        token=factories.make_address(),
        pkey=factories.HOP1_KEY,
        sender=factories.HOP1,
    )

    return signed_transfer
Ejemplo n.º 9
0
    def unlock(self, ctx, locked_encoded, merkleproof_encoded, secret):
        if self.settled is not None:
            raise RuntimeError('Contract is settled.')

        if self.closed is None:
            raise RuntimeError('Contract is open.')

        if ctx['msg.sender'] not in self.participants:
            raise ValueError('Unknow address.')

        partner = self.partner(ctx['msg.sender'])
        state = self.participants[partner]
        transfer = state.transfer

        # if partner haven't made a single transfer
        if transfer is None:
            return

        merkle_proof = tuple32(merkleproof_encoded)
        lock = Lock.from_bytes(locked_encoded)

        hashlock = lock.hashlock
        if hashlock != sha3(secret):
            raise ValueError('Invalid secret')

        is_valid_proof = check_proof(
            merkle_proof,
            transfer.locksroot,
            sha3(transfer.lock.as_bytes),
        )

        if not is_valid_proof:
            raise ValueError('Invalid merkle proof')

        transfer.append(lock)
Ejemplo n.º 10
0
 def _update_balance_proof_data(self, partner, amount, expiration, secret):
     expected = self._get_balance_proof_data(partner)
     lock = Lock(amount=amount,
                 expiration=expiration,
                 secrethash=sha3(secret))
     expected.update(amount, lock.lockhash)
     return expected
Ejemplo n.º 11
0
def test_receive_hashlocktransfer_unknown(raiden_network):
    app0 = raiden_network[0]  # pylint: disable=unbalanced-tuple-unpacking

    graph0 = app0.raiden.channelgraphs.values()[0]

    other_key = PrivateKey(HASH2)
    other_address = privatekey_to_address(HASH2)
    amount = 10
    lock = Lock(amount, 1, HASH)
    refund_transfer = RefundTransfer(
        identifier=1,
        nonce=1,
        token=graph0.token_address,
        transferred_amount=amount,
        recipient=app0.raiden.address,
        locksroot=HASH,
        lock=lock
    )
    sign_and_send(refund_transfer, other_key, other_address, app0)

    secret = Secret(1, HASH, graph0.token_address)
    sign_and_send(secret, other_key, other_address, app0)

    secret_request = SecretRequest(1, HASH, 1)
    sign_and_send(secret_request, other_key, other_address, app0)

    reveal_secret = RevealSecret(HASH)
    sign_and_send(reveal_secret, other_key, other_address, app0)
Ejemplo n.º 12
0
def test_decode_refund_transfer(settle_timeout, tester_state, tester_token):
    privatekey0 = tester.DEFAULT_KEY
    privatekey1 = tester.k1
    address0 = privatekey_to_address(privatekey0)
    address1 = privatekey_to_address(privatekey1)

    dtester = deploy_decoder_tester(tester_state, tester_token.address,
                                    address0, address1, settle_timeout)

    locksroot = sha3('Mainz')
    amount = 1337
    expiration = 19
    lock = Lock(amount, expiration, locksroot)

    message = RefundTransfer(identifier=321313,
                             nonce=4242452,
                             token=tester_token.address,
                             transferred_amount=amount,
                             recipient=address1,
                             locksroot=locksroot,
                             lock=lock)

    message.sign(PrivateKey(privatekey0, ctx=GLOBAL_CTX, raw=True), address0)
    _, publickey = wrap_and_validate(message.encode())
    recovered_address = address_from_key(publickey)
    assert recovered_address == address0

    assert dtester.testDecodeTransfer(message.encode(),
                                      sender=privatekey1) is True
    assert dtester.decodedNonce() == 4242452
    assert dtester.decodedToken() == tester_token.address.encode('hex')
    assert dtester.decodedLocksroot() == locksroot
Ejemplo n.º 13
0
def _(properties, defaults=None) -> LockedTransferSignedState:
    transfer: LockedTransferSignedStateProperties = create_properties(
        properties, defaults)
    params = {key: value for key, value in transfer.__dict__.items()}

    lock = Lock(amount=transfer.amount,
                expiration=transfer.expiration,
                secrethash=sha3(transfer.secret))

    pkey = params.pop("pkey")
    signer = LocalSigner(pkey)
    sender = params.pop("sender")
    canonical_identifier = params.pop("canonical_identifier")
    params["chain_id"] = int(canonical_identifier.chain_identifier)
    params["channel_identifier"] = int(canonical_identifier.channel_identifier)
    params[
        "token_network_address"] = canonical_identifier.token_network_address
    if params["locksroot"] == EMPTY_MERKLE_ROOT:
        params["locksroot"] = lock.lockhash

    locked_transfer = LockedTransfer(lock=lock, **params)
    locked_transfer.sign(signer)

    assert locked_transfer.sender == sender

    return lockedtransfersigned_from_message(locked_transfer)
def test_receive_lockedtransfer_invalidnonce(
        raiden_network,
        deposit,
        token_addresses,
        reveal_timeout,
        network_wait
):

    app0, app1, app2 = raiden_network
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )
    channel0 = get_channelstate(app0, app1, token_network_identifier)

    amount = 10
    mediated_transfer(
        app0,
        app2,
        token_network_identifier,
        amount,
        timeout=network_wait,
    )

    amount = 10
    payment_identifier = 1
    repeated_nonce = 1
    expiration = reveal_timeout * 2
    mediated_transfer_message = LockedTransfer(
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=payment_identifier,
        nonce=repeated_nonce,
        token_network_address=token_network_identifier,
        token=token_address,
        channel=channel0.identifier,
        transferred_amount=amount,
        locked_amount=amount,
        recipient=app1.raiden.address,
        locksroot=UNIT_SECRETHASH,
        lock=Lock(amount, expiration, UNIT_SECRETHASH),
        target=app2.raiden.address,
        initiator=app0.raiden.address,
        fee=0,
    )

    sign_and_inject(
        mediated_transfer_message,
        app0.raiden.private_key,
        app0.raiden.address,
        app1,
    )

    assert_synched_channel_state(
        token_network_identifier,
        app0, deposit - amount, [],
        app1, deposit + amount, [],
    )
Ejemplo n.º 15
0
def run_test_receive_lockedtransfer_invalidnonce(raiden_network,
                                                 number_of_nodes, deposit,
                                                 token_addresses,
                                                 reveal_timeout, network_wait):

    app0, app1, app2 = raiden_network
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0), app0.raiden.default_registry.address,
        token_address)
    channel0 = get_channelstate(app0, app1, token_network_identifier)

    amount = 10
    transfer(
        initiator_app=app0,
        target_app=app2,
        token_address=token_address,
        amount=amount,
        identifier=1,
        timeout=network_wait * number_of_nodes,
    )

    amount = 10
    payment_identifier = 1
    repeated_nonce = 1
    expiration = reveal_timeout * 2
    mediated_transfer_message = LockedTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=payment_identifier,
        nonce=repeated_nonce,
        token_network_address=token_network_identifier,
        token=token_address,
        channel_identifier=channel0.identifier,
        transferred_amount=amount,
        locked_amount=amount,
        recipient=app1.raiden.address,
        locksroot=UNIT_SECRETHASH,
        lock=Lock(amount=amount,
                  expiration=expiration,
                  secrethash=UNIT_SECRETHASH),
        target=app2.raiden.address,
        initiator=app0.raiden.address,
        fee=0,
    )

    sign_and_inject(mediated_transfer_message, app0.raiden.signer, app1)

    with gevent.Timeout(network_wait):
        wait_assert(
            assert_synced_channel_state,
            token_network_identifier,
            app0,
            deposit - amount,
            [],
            app1,
            deposit + amount,
            [],
        )
Ejemplo n.º 16
0
def test_settle_with_locked_mediated_transfer_for_counterparty(
        deposit, settle_timeout, reveal_timeout, tester_chain, tester_channels,
        tester_token):
    """ Test settle with a locked mediated transfer for the counter party. """

    pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0]
    payment_network_identifier = factories.make_address()

    address0 = privatekey_to_address(pkey0)
    address1 = privatekey_to_address(pkey1)

    initial0 = tester_token.balanceOf(address0, sender=pkey0)
    initial1 = tester_token.balanceOf(address1, sender=pkey0)

    transferred_amount0 = 30
    increase_transferred_amount(
        payment_network_identifier,
        channel0,
        channel1,
        transferred_amount0,
        pkey0,
    )

    expiration0 = tester_chain.block.number + reveal_timeout + 5
    new_block = Block(tester_chain.block.number)
    channel.state_transition(channel0, new_block, new_block.block_number)
    channel.state_transition(channel1, new_block, new_block.block_number)
    lock0 = Lock(amount=29, expiration=expiration0, secrethash=sha3(b'lock1'))
    mediated0 = make_mediated_transfer(
        channel0,
        channel1,
        address0,
        address1,
        lock0,
        pkey0,
    )

    nettingchannel.close(sender=pkey0)

    mediated0_hash = sha3(mediated0.packed().data[:-65])
    nettingchannel.updateTransfer(
        mediated0.nonce,
        mediated0.transferred_amount,
        mediated0.locksroot,
        mediated0_hash,
        mediated0.signature,
        sender=pkey1,
    )

    tester_chain.mine(number_of_blocks=settle_timeout + 1)
    nettingchannel.settle(sender=pkey1)

    # the balances only change by transferred_amount because the lock was /not/ unlocked
    balance0 = initial0 + deposit - transferred_amount0
    balance1 = initial1 + transferred_amount0

    assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
    assert tester_token.balanceOf(address0, sender=pkey0) == balance0
    assert tester_token.balanceOf(address1, sender=pkey0) == balance1
Ejemplo n.º 17
0
    def create_lockedtransfer(self, amount, expiration, hashlock):
        """ Return a LockedTransfer message.

        This message needs to be signed and registered with the channel before sent.
        """
        if not self.isopen:
            raise ValueError('The channel is closed')

        block_number = self.external_state.get_block_number()

        # expiration is not sufficient for guarantee settling
        if expiration - block_number >= self.settle_timeout:
            log.debug(
                "Transfer expiration doesn't allow for corret settlement.",
                expiration=expiration,
                block_number=block_number,
                settle_timeout=self.settle_timeout,
            )

            raise ValueError('Invalid expiration')

        if expiration - self.reveal_timeout < block_number:
            log.debug(
                'Expiration smaller than the minimum requried.',
                expiration=expiration,
                block_number=block_number,
                reveal_timeout=self.reveal_timeout,
            )

            raise ValueError('Invalid expiration')

        from_ = self.our_state
        to_ = self.partner_state

        distributable = from_.distributable(to_)

        if amount <= 0 or amount > distributable:
            log.debug(
                'Insufficient funds',
                amount=amount,
                distributable=distributable,
            )
            raise ValueError('Insufficient funds')

        lock = Lock(amount, expiration, hashlock)

        # start of critical read section
        transfered_amount = from_.transfered_amount
        updated_locksroot = to_.locked.root_with(lock)
        # end of critical read section

        return LockedTransfer(
            nonce=from_.nonce,
            asset=self.asset_address,
            transfered_amount=transfered_amount,
            recipient=to_.address,
            locksroot=updated_locksroot,
            lock=lock,
        )
Ejemplo n.º 18
0
def test_mediated_transfer():
    nonce = balance = 1
    asset = recipient = target = initiator = address
    hashlock = locksroot = sha3(address)
    amount = expiration = 1
    lock = Lock(amount, expiration, hashlock)

    d = lock.encode()
    assert Lock.decode(d) == lock

    msg = MediatedTransfer(nonce, asset, balance, recipient, locksroot,
                           lock, target, initiator, fee=0)
    msg.sign(privkey)
    dm = msg.encode()
    msg2 = decode(dm)
    assert msg2 == msg
    assert msg2.lock == lock
Ejemplo n.º 19
0
def make_signed_transfer(
        amount,
        initiator,
        target,
        expiration,
        secret,
        payment_identifier=1,
        message_identifier=None,
        nonce=1,
        transferred_amount=0,
        locked_amount=None,
        locksroot=EMPTY_MERKLE_ROOT,
        recipient=UNIT_TRANSFER_TARGET,
        channel_identifier=UNIT_CHANNEL_ID,
        token_network_address=UNIT_TOKEN_NETWORK_ADDRESS,
        token=UNIT_TOKEN_ADDRESS,
        pkey=UNIT_TRANSFER_PKEY,
        sender=UNIT_TRANSFER_SENDER,
):

    if message_identifier is None:
        message_identifier = random.randint(0, UINT64_MAX)

    secrethash = sha3(secret)
    lock = Lock(
        amount,
        expiration,
        secrethash,
    )

    if locksroot == EMPTY_MERKLE_ROOT:
        locksroot = sha3(lock.as_bytes)

    if locked_amount is None:
        locked_amount = amount
    else:
        assert locked_amount >= amount

    transfer = LockedTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=message_identifier,
        payment_identifier=payment_identifier,
        nonce=nonce,
        token_network_address=token_network_address,
        token=token,
        channel_identifier=channel_identifier,
        transferred_amount=transferred_amount,
        locked_amount=locked_amount,
        recipient=recipient,
        locksroot=locksroot,
        lock=lock,
        target=target,
        initiator=initiator,
    )
    transfer.sign(pkey)
    assert transfer.sender == sender

    return lockedtransfersigned_from_message(transfer)
Ejemplo n.º 20
0
def test_received_lockedtransfer_closedchannel(raiden_network, reveal_timeout,
                                               token_addresses, deposit):

    app0, app1 = raiden_network
    registry_address = app0.raiden.default_registry.address
    token_address = token_addresses[0]
    channel0 = get_channelstate(app0, app1, token_address)

    RaidenAPI(app1.raiden).channel_close(
        registry_address,
        token_address,
        app0.raiden.address,
    )

    wait_until_block(
        app0.raiden.chain,
        app0.raiden.chain.block_number() + 1,
    )

    # Now receive one mediated transfer for the closed channel
    lock_amount = 10
    payment_identifier = 1
    expiration = reveal_timeout * 2
    mediated_transfer_message = LockedTransfer(
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=payment_identifier,
        nonce=1,
        registry_address=app0.raiden.default_registry.address,
        token=token_address,
        channel=channel0.identifier,
        transferred_amount=0,
        locked_amount=lock_amount,
        recipient=app1.raiden.address,
        locksroot=UNIT_SECRETHASH,
        lock=Lock(lock_amount, expiration, UNIT_SECRETHASH),
        target=app1.raiden.address,
        initiator=app0.raiden.address,
        fee=0)

    sign_and_inject(
        mediated_transfer_message,
        app0.raiden.private_key,
        app0.raiden.address,
        app1,
    )

    # The local state must not change since the channel is already closed
    assert_synched_channel_state(
        token_address,
        app0,
        deposit,
        [],
        app1,
        deposit,
        [],
    )
Ejemplo n.º 21
0
def test_unlock(deposit, settle_timeout, reveal_timeout, tester_channels,
                tester_state, tester_token):

    pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0]

    address0 = privatekey_to_address(pkey0)
    address1 = privatekey_to_address(pkey1)

    initial_balance0 = tester_token.balanceOf(address0, sender=pkey0)
    initial_balance1 = tester_token.balanceOf(address1, sender=pkey0)

    lock_amount = 31
    lock_expiration = tester_state.block.number + reveal_timeout + 5
    secret = 'secretsecretsecretsecretsecretse'
    hashlock = sha3(secret)
    new_block = Block(tester_state.block.number)
    channel0.state_transition(new_block)
    channel1.state_transition(new_block)
    lock0 = Lock(lock_amount, lock_expiration, hashlock)

    mediated0 = make_mediated_transfer(
        channel0,
        channel1,
        address0,
        address1,
        lock0,
        pkey0,
        tester_state.block.number,
        secret,
    )
    mediated0_data = str(mediated0.packed().data)

    proof = channel1.our_state.balance_proof.compute_proof_for_lock(
        secret,
        mediated0.lock,
    )

    nettingchannel.close(mediated0_data, sender=pkey1)

    tester_state.mine(number_of_blocks=1)

    nettingchannel.unlock(
        proof.lock_encoded,
        ''.join(proof.merkle_proof),
        proof.secret,
        sender=pkey1,
    )

    tester_state.mine(number_of_blocks=settle_timeout + 1)
    nettingchannel.settle(sender=pkey0)

    balance0 = initial_balance0 + deposit - lock0.amount
    balance1 = initial_balance1 + deposit + lock0.amount
    assert tester_token.balanceOf(address0, sender=pkey0) == balance0
    assert tester_token.balanceOf(address1, sender=pkey0) == balance1
    assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
Ejemplo n.º 22
0
def test_withdraw_expired_lock(reveal_timeout, tester_channels, tester_chain):
    pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0]
    pseudo_random_generator = random.Random()

    lock_timeout = reveal_timeout + 5
    lock_expiration = tester_chain.block.number + lock_timeout
    secret = b'expiredlockexpiredlockexpiredloc'
    secrethash = sha3(secret)
    new_block = Block(tester_chain.block.number)
    channel.state_transition(
        channel0,
        new_block,
        pseudo_random_generator,
        new_block.block_number,
    )
    channel.state_transition(
        channel1,
        new_block,
        pseudo_random_generator,
        new_block.block_number,
    )
    lock1 = Lock(amount=31, expiration=lock_expiration, secrethash=secrethash)

    mediated0 = make_mediated_transfer(
        channel1,
        channel0,
        privatekey_to_address(pkey0),
        privatekey_to_address(pkey1),
        lock1,
        pkey1,
        secret,
    )

    mediated0_hash = sha3(mediated0.packed().data[:-65])
    nettingchannel.close(
        mediated0.nonce,
        mediated0.transferred_amount,
        mediated0.locksroot,
        mediated0_hash,
        mediated0.signature,
        sender=pkey0,
    )

    # expire the lock
    tester_chain.mine(number_of_blocks=lock_timeout + 1)

    unlock_proofs = channel.get_known_unlocks(channel0.partner_state)
    proof = unlock_proofs[0]

    with pytest.raises(TransactionFailed):
        nettingchannel.withdraw(
            proof.lock_encoded,
            b''.join(proof.merkle_proof),
            proof.secret,
            sender=pkey0,
        )
def test_receive_lockedtransfer_invalidrecipient(
    raiden_network,
    token_addresses,
    reveal_timeout,
    deposit,
):

    app0, app1 = raiden_network
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )
    channel0 = get_channelstate(app0, app1, token_network_identifier)

    payment_identifier = 1
    invalid_recipient = make_address()
    lock_amount = 10
    expiration = reveal_timeout * 2
    mediated_transfer_message = LockedTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=payment_identifier,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel_identifier=channel0.identifier,
        transferred_amount=0,
        locked_amount=lock_amount,
        recipient=invalid_recipient,
        locksroot=UNIT_SECRETHASH,
        lock=Lock(amount=lock_amount,
                  expiration=expiration,
                  secrethash=UNIT_SECRETHASH),
        target=app1.raiden.address,
        initiator=app0.raiden.address,
        fee=0,
    )

    sign_and_inject(
        mediated_transfer_message,
        app0.raiden.signer,
        app1,
    )

    assert_synced_channel_state(
        token_network_identifier,
        app0,
        deposit,
        [],
        app1,
        deposit,
        [],
    )
Ejemplo n.º 24
0
def make_signed_transfer(
    amount,
    initiator,
    target,
    expiration,
    secret,
    payment_identifier=1,
    message_identifier=None,
    nonce=1,
    transferred_amount=0,
    locked_amount=None,
    recipient=UNIT_TRANSFER_TARGET,
    channel_identifier=UNIT_CHANNEL_ADDRESS,
    token=UNIT_TOKEN_ADDRESS,
    pkey=UNIT_TRANSFER_PKEY,
    sender=UNIT_TRANSFER_SENDER,
):

    if message_identifier is None:
        message_identifier = random.randint(0, UINT64_MAX)

    secrethash = sha3(secret)
    lock = Lock(
        amount,
        expiration,
        secrethash,
    )

    if locked_amount is None:
        locked_amount = amount
    else:
        assert locked_amount >= amount

    transfer = LockedTransfer(
        message_identifier,
        payment_identifier,
        nonce,
        UNIT_REGISTRY_IDENTIFIER,
        token,
        channel_identifier,
        transferred_amount,
        locked_amount,
        recipient,
        lock.lockhash,
        lock,
        target,
        initiator,
    )
    transfer.sign(pkey)
    assert transfer.sender == sender

    return lockedtransfersigned_from_message(transfer)
Ejemplo n.º 25
0
def test_mediated_after_direct_transfer(reveal_timeout, settle_timeout,
                                        deposit, tester_state, tester_channels,
                                        tester_token):
    """ The transfer types must not change the behavior of the dispute. """

    pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0]

    address0 = privatekey_to_address(pkey0)
    address1 = privatekey_to_address(pkey1)

    initial_balance0 = tester_token.balanceOf(address0, sender=pkey0)
    initial_balance1 = tester_token.balanceOf(address1, sender=pkey0)

    first_amount0 = 90
    block_number = tester_state.block.number
    make_direct_transfer_from_channel(
        block_number,
        channel0,
        channel1,
        first_amount0,
        pkey0,
    )

    lock_expiration = tester_state.block.number + reveal_timeout + 5
    new_block = Block(tester_state.block.number)
    channel0.state_transition(new_block)
    channel1.state_transition(new_block)
    lock1 = Lock(amount=31, expiration=lock_expiration, hashlock=sha3('lock2'))
    second_mediated0 = make_mediated_transfer(
        channel0,
        channel1,
        address0,
        address1,
        lock1,
        pkey0,
        tester_state.block.number,
    )
    second_mediated0_data = str(second_mediated0.packed().data)

    nettingchannel.close('', sender=pkey0)
    nettingchannel.updateTransfer(second_mediated0_data, sender=pkey1)

    tester_state.mine(number_of_blocks=settle_timeout + 1)
    nettingchannel.settle(sender=pkey0)

    # the balances only change by transferred_amount because the lock was /not/ unlocked
    balance0 = initial_balance0 + deposit - first_amount0
    balance1 = initial_balance1 + deposit + first_amount0

    assert tester_token.balanceOf(nettingchannel.address, sender=pkey1) == 0
    assert tester_token.balanceOf(address0, sender=pkey0) == balance0
    assert tester_token.balanceOf(address1, sender=pkey1) == balance1
Ejemplo n.º 26
0
def test_receive_lockedtransfer_invalidsender(
    raiden_network,
    token_addresses,
    deposit,
    reveal_timeout,
):

    app0, app1 = raiden_network
    token_address = token_addresses[0]
    other_key, other_address = make_privkey_address()

    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )
    channel0 = get_channelstate(app0, app1, token_network_identifier)
    lock_amount = 10
    expiration = reveal_timeout * 2
    mediated_transfer_message = LockedTransfer(
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=1,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel=channel0.identifier,
        transferred_amount=0,
        locked_amount=lock_amount,
        recipient=app0.raiden.address,
        locksroot=UNIT_SECRETHASH,
        lock=Lock(lock_amount, expiration, UNIT_SECRETHASH),
        target=app0.raiden.address,
        initiator=other_address,
        fee=0,
    )

    sign_and_inject(
        mediated_transfer_message,
        other_key,
        other_address,
        app0,
    )

    assert_synched_channel_state(
        token_network_identifier,
        app0,
        deposit,
        [],
        app1,
        deposit,
        [],
    )
Ejemplo n.º 27
0
def test_receive_mediatedtransfer_invalidnonce(raiden_network, deposit,
                                               token_addresses, reveal_timeout,
                                               network_wait):

    app0, app1, app2 = raiden_network
    token_address = token_addresses[0]
    channel0 = get_channelstate(app0, app1, token_address)

    amount = 10
    mediated_transfer(
        app0,
        app2,
        token_address,
        amount,
        timeout=network_wait,
    )

    amount = 10
    identifier = 1
    repeated_nonce = 1
    expiration = reveal_timeout * 2
    mediated_transfer_message = MediatedTransfer(
        identifier=identifier,
        nonce=repeated_nonce,
        token=token_address,
        channel=channel0.identifier,
        transferred_amount=amount,
        recipient=app1.raiden.address,
        locksroot=UNIT_SECRETHASH,
        lock=Lock(amount, expiration, UNIT_SECRETHASH),
        target=app2.raiden.address,
        initiator=app0.raiden.address,
        fee=0,
    )

    sign_and_inject(
        mediated_transfer_message,
        app0.raiden.private_key,
        app0.raiden.address,
        app1,
    )

    assert_synched_channel_state(
        token_address,
        app0,
        deposit - amount,
        [],
        app1,
        deposit + amount,
        [],
    )
Ejemplo n.º 28
0
    def create_lockedtransfer(self, block_number, amount, identifier,
                              expiration, hashlock):
        """ Return a LockedTransfer message.

        This message needs to be signed and registered with the channel before sent.
        """
        timeout = expiration - block_number

        if not self.can_transfer:
            raise ValueError(
                'Transfer not possible, no funding or channel closed.')

        # the expiration cannot be lower than the reveal timeout (otherwise we
        # dont have enough time to listen for the ChannelSecretRevealed event)
        if timeout <= self.reveal_timeout:
            log.debug(
                'Lock expiration is lower than reveal timeout.',
                expiration=expiration,
                block_number=self.block_number,
                reveal_timeout=self.reveal_timeout,
            )

            raise ValueError('Invalid expiration.')

        from_ = self.our_state
        to_ = self.partner_state

        distributable = from_.distributable(to_)

        if amount <= 0 or amount > distributable:
            log.debug(
                'Insufficient funds',
                amount=amount,
                distributable=distributable,
            )
            raise ValueError('Insufficient funds')

        lock = Lock(amount, expiration, hashlock)

        updated_locksroot = to_.compute_merkleroot_with(include=lock)
        transferred_amount = from_.transferred_amount

        return LockedTransfer(
            identifier=identifier,
            nonce=from_.nonce,
            token=self.token_address,
            transferred_amount=transferred_amount,
            recipient=to_.address,
            locksroot=updated_locksroot,
            lock=lock,
        )
Ejemplo n.º 29
0
def test_settle_with_locked_mediated_transfer_for_counterparty(
        deposit,
        settle_timeout,
        reveal_timeout,
        tester_state,
        tester_channels,
        tester_token):

    """ Test settle with a locked mediated transfer for the counter party. """

    pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0]
    address0 = privatekey_to_address(pkey0)
    address1 = privatekey_to_address(pkey1)

    initial0 = tester_token.balanceOf(address0, sender=pkey0)
    initial1 = tester_token.balanceOf(address1, sender=pkey0)

    transferred_amount0 = 30
    increase_transferred_amount(channel0, channel1, transferred_amount0)

    expiration0 = tester_state.block.number + reveal_timeout + 5
    new_block = Block(tester_state.block.number)
    channel0.state_transition(new_block)
    channel1.state_transition(new_block)
    lock0 = Lock(amount=29, expiration=expiration0, hashlock=sha3('lock1'))
    mediated = make_mediated_transfer(
        channel0,
        channel1,
        address0,
        address1,
        lock0,
        pkey0,
        tester_state.block.number,
    )

    nettingchannel.close('', sender=pkey0)

    transfer_data = str(mediated.packed().data)
    nettingchannel.updateTransfer(transfer_data, sender=pkey1)

    tester_state.mine(number_of_blocks=settle_timeout + 1)
    nettingchannel.settle(sender=pkey1)

    # the balances only change by transferred_amount because the lock was /not/ unlocked
    balance0 = initial0 + deposit - transferred_amount0
    balance1 = initial1 + transferred_amount0

    assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
    assert tester_token.balanceOf(address0, sender=pkey0) == balance0
    assert tester_token.balanceOf(address1, sender=pkey0) == balance1
Ejemplo n.º 30
0
def handle_contract_send_channelunlock(
        raiden: RaidenService,
        channel_unlock_event: ContractSendChannelBatchUnlock,
):
    channel = raiden.chain.netting_channel(channel_unlock_event.channel_identifier)
    block_number = raiden.get_block_number()

    for unlock_proof in channel_unlock_event.unlock_proofs:
        lock = Lock.from_bytes(unlock_proof.lock_encoded)

        if lock.expiration < block_number:
            log.error('Lock has expired!', lock=lock)
        else:
            channel.unlock(unlock_proof)
Ejemplo n.º 31
0
def test_locked_transfer(iterations=ITERATIONS):
    amount = 1
    expiration = 1
    hashlock = sha3(ADDRESS)
    lock = Lock(amount, expiration, hashlock)

    nonce = 1
    asset = ADDRESS
    balance = 1
    recipient = ADDRESS
    locksroot = sha3(ADDRESS)
    msg = LockedTransfer(nonce, asset, balance, recipient, locksroot, lock)
    msg.sign(PRIVKEY)
    run_timeit('LockedTransfer', msg, iterations=iterations)
Ejemplo n.º 32
0
def handle_contract_channelwithdraw(
        raiden: 'RaidenService',
        channel_withdraw_event: ContractSendChannelWithdraw):
    channel = raiden.chain.netting_channel(
        channel_withdraw_event.channel_identifier)
    block_number = raiden.get_block_number()

    for unlock_proof in channel_withdraw_event.unlock_proofs:
        lock = Lock.from_bytes(unlock_proof.lock_encoded)

        if lock.expiration < block_number:
            log.error('Lock has expired!', lock=lock)
        else:
            channel.withdraw(unlock_proof)
Ejemplo n.º 33
0
    def close(self, ctx, sender, transfers_encoded, locked_encoded,  # noqa
              merkleproof_encoded, secret):
        """" Request the closing of the channel. Can be called multiple times.
        lock period starts with first valid call.

        Args:
            sender (address):
                The sender address.

            transfers_encoded (List[transfer]):
                A list of maximum length of 2 containing the transfer encoded
                using the fixed length format, may be empty.

            ctx:
                Block chain state used for mocking.

            locked_encoded (bin):
                The Lock to be unlocked.

            merkleproof_encoded (bin):
                A proof that the given lock is contained in the latest
                transfer. The binary data is composed of a single hash at every
                4bytes.

            secret (bin):
                The secret that unlocks the lock `hashlock = sha3(secret)`.

        Todo:
            if challenged, keep track of who provided the last valid answer,
            punish the wrongdoer here, check that participants only updates
            their own balance are counted, because they could sign something
            for the other party to blame it.
        """
        # pylint: disable=too-many-arguments,too-many-locals,too-many-branches
        # if len(transfers_encoded):
        #     raise ValueError('transfers_encoded needs at least 1 item.')

        if len(transfers_encoded) > 2:
            raise ValueError('transfers_encoded cannot have more than 2 items.')

        if self.settled:
            raise RuntimeError('contract is settled')

        # the merkleproof can be empty, if there is only one haslock
        has_oneofunlocked = locked_encoded or secret
        has_allofunlocked = locked_encoded and secret
        if has_oneofunlocked and not has_allofunlocked:
            raise ValueError(
                'all arguments `merkle_proof`, `locked`, and `secret` must be provided'
            )

        last_sent_transfers = []
        for data in transfers_encoded:
            if data[0] == DIRECTTRANSFER:
                last_sent_transfers.append(
                    DirectTransfer.decode(data)
                )
            elif data[0] == MEDIATEDTRANSFER:
                last_sent_transfers.append(
                    MediatedTransfer.decode(data)
                )
            elif data[0] == CANCELTRANSFER:
                last_sent_transfers.append(
                    CancelTransfer.decode(data)
                )
            # convinience for testing only (LockedTransfer are not exchanged between nodes)
            elif data[0] == LOCKEDTRANSFER:
                last_sent_transfers.append(
                    LockedTransfer.decode(data)
                )
            else:
                raise ValueError('invalid transfer type {}'.format(type(data[0])))

        # keep the latest claim
        for transfer in last_sent_transfers:
            if transfer.sender not in self.participants:
                raise ValueError('Invalid tansfer, sender is not a participant')

            sender_state = self.participants[transfer.sender]

            if is_newer_transfer(transfer, sender_state):
                sender_state['last_sent_transfer'] = transfer

        partner = self.partner(sender)
        partner_state = self.participants[partner]

        if last_sent_transfers:
            transfer = last_sent_transfers[-1]  # XXX: check me

        # register un-locked
        if merkleproof_encoded:
            merkle_proof = tuple32(merkleproof_encoded)
            lock = Lock.from_bytes(locked_encoded)

            hashlock = lock.hashlock
            if hashlock != sha3(secret):
                raise ValueError('invalid secret')

            # the partner might not have made a transfer
            if partner_state['last_sent_transfer'] is not None:
                assert check_proof(
                    merkle_proof,
                    partner_state['last_sent_transfer'].locksroot,
                    sha3(transfer.lock.as_bytes),
                )

            partner_state['unlocked'].append(lock)

        if self.closed is None:
            log.debug('closing contract', netcontract_address=pex(self.netcontract_address))
            self.closed = ctx['block_number']