Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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,
        )
Пример #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
Пример #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)
Пример #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
Пример #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)
Пример #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
Пример #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, [],
    )
Пример #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,
            [],
        )
Пример #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
Пример #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,
        )
Пример #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
Пример #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)
Пример #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,
        [],
    )
Пример #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
Пример #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,
        [],
    )
Пример #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)
Пример #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
Пример #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,
        [],
    )
Пример #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,
        [],
    )
Пример #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,
        )
Пример #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
Пример #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)
Пример #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)
Пример #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)
Пример #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']