Example #1
0
def test_mediated_transfer(iterations=ITERATIONS):
    identifier = 1
    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(
        identifier,
        nonce,
        asset,
        balance,
        recipient,
        locksroot,
        lock,
        target,
        initiator,
        fee=0,
    )
    msg.sign(PRIVKEY, ADDRESS)

    run_timeit('MediatedTranfer', msg, iterations=iterations)
Example #2
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
def test_decode_mediated_transfer(
        private_keys,
        settle_timeout,
        tester_state,
        tester_token,
        tester_events,
        tester_registry):

    privatekey0 = tester.DEFAULT_KEY
    privatekey1 = private_keys[1]
    address0 = privatekey_to_address(privatekey0)
    address1 = privatekey_to_address(privatekey1)
    address2 = privatekey_to_address(private_keys[2])

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

    locksroot = sha3("Sikorka")
    amount = 1337
    expiration = 5
    lock = Lock(amount, expiration, locksroot)

    message = MediatedTransfer(
        identifier=313151,
        nonce=88924902,
        asset=tester_token.address,
        transferred_amount=amount,
        recipient=address1,
        locksroot=locksroot,
        lock=lock,
        target=address2,
        initiator=address0
    )

    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()) is True
    assert dtester.decodedNonce() == 88924902
    assert dtester.decodedExpiration() == expiration
    assert dtester.decodedAsset() == tester_token.address.encode('hex')
    assert dtester.decodedRecipient() == address1.encode('hex')
    assert dtester.decodedAmount() == amount
    assert dtester.decodedLocksroot() == locksroot
Example #4
0
def decode_transfer(transfer_encoded):
    if transfer_encoded[0] == DIRECTTRANSFER:
        return DirectTransfer.decode(transfer_encoded)
    elif transfer_encoded[0] == MEDIATEDTRANSFER:
        return MediatedTransfer.decode(transfer_encoded)
    elif transfer_encoded[0] == CANCELTRANSFER:
        return CancelTransfer.decode(transfer_encoded)
    # convinience for testing only (LockedTransfer are not exchanged between nodes)
    elif transfer_encoded[0] == LOCKEDTRANSFER:
        return LockedTransfer.decode(transfer_encoded)
    else:
        raise ValueError('invalid transfer type {}'.format(type(transfer_encoded[0])))
Example #5
0
def test_mediated_transfer():
    nonce = balance = 1
    asset = recipient = target = initiator = ADDRESS
    hashlock = locksroot = sha3(ADDRESS)
    amount = expiration = 1
    fee = 0

    lock = Lock(amount, expiration, hashlock)
    mediated_transfer = MediatedTransfer(
        nonce,
        asset,
        balance,
        recipient,
        locksroot,
        lock,
        target,
        initiator,
        fee,
    )
    mediated_transfer.sign(PRIVKEY)
    decoded_mediated_transfer = decode(mediated_transfer.encode())
    assert decoded_mediated_transfer == mediated_transfer
Example #6
0
def test_receive_mediatedtransfer_unknown(raiden_network):
    app0 = raiden_network[0]  # pylint: disable=unbalanced-tuple-unpacking
    graph0 = app0.raiden.token_to_channelgraph.values()[0]

    other_key, other_address = make_privkey_address()
    amount = 10
    mediated_transfer = MediatedTransfer(identifier=1,
                                         nonce=1,
                                         token=graph0.token_address,
                                         channel=other_address,
                                         transferred_amount=amount,
                                         recipient=app0.raiden.address,
                                         locksroot=UNIT_HASHLOCK,
                                         lock=Lock(amount, 1, UNIT_HASHLOCK),
                                         target=make_address(),
                                         initiator=other_address,
                                         fee=0)
    sign_and_send(mediated_transfer, other_key, other_address, app0)
Example #7
0
def test_receive_mediatedtransfer_outoforder(raiden_network, private_keys):
    alice_app = raiden_network[0]
    setup_messages_cb()

    graph = alice_app.raiden.channelgraphs.values()[0]
    token_address = graph.token_address

    mt_helper = MediatedTransferTestHelper(raiden_network, graph)
    initiator_address = alice_app.raiden.address
    path = mt_helper.get_paths_of_length(initiator_address, 2)

    alice_address, bob_address, charlie_address = path
    amount = 10
    result = alice_app.raiden.transfer_async(
        token_address,
        amount,
        charlie_address,
    )

    assert result.wait(timeout=10)
    gevent.sleep(1.)

    # and now send one more mediated transfer with the same nonce, simulating
    # an out-of-order/resent message that arrives late
    locksroot = HASH
    lock = Lock(amount, 1, locksroot)
    identifier = create_default_identifier(
        alice_app.raiden.address,
        graph.token_address,
        charlie_address,
    )
    mediated_transfer = MediatedTransfer(identifier=identifier,
                                         nonce=1,
                                         token=token_address,
                                         transferred_amount=amount,
                                         recipient=bob_address,
                                         locksroot=locksroot,
                                         lock=lock,
                                         target=charlie_address,
                                         initiator=initiator_address,
                                         fee=0)
    alice_key = PrivateKey(private_keys[0])
    bob_app = mt_helper.get_app_from_address(bob_address)
    sign_and_send(mediated_transfer, alice_key, alice_address, bob_app)
Example #8
0
def test_receive_mediatedtransfer_invalid_address(raiden_network,
                                                  private_keys):
    alice_app = raiden_network[0]
    setup_messages_cb()

    token_manager = alice_app.raiden.managers_by_token_address.values()[0]
    token_address = token_manager.token_address

    mt_helper = MediatedTransferTestHelper(raiden_network, token_manager)
    initiator_address = alice_app.raiden.address
    path = mt_helper.get_paths_of_length(initiator_address, 2)

    alice_address, bob_address, charlie_address = path
    amount = 10
    alice_app.raiden.api.transfer(
        token_address,
        amount,
        charlie_address,
    )
    gevent.sleep(1.)

    # and now send one more mediated transfer with the same nonce, simulating
    # an out-of-order/resent message that arrives late
    locksroot = HASH
    lock = Lock(amount, 1, locksroot)
    mediated_transfer = MediatedTransfer(
        identifier=token_manager.transfermanager.create_default_identifier(
            charlie_address),
        nonce=1,
        token=token_address,
        transferred_amount=amount,
        recipient=bob_address,
        locksroot=locksroot,
        lock=lock,
        target=charlie_address,
        initiator=initiator_address,
        fee=0)
    alice_key = PrivateKey(private_keys[0])
    target_app = None
    for app in raiden_network:
        if app.raiden.address not in path:
            target_app = app
            break
    sign_and_send(mediated_transfer, alice_key, alice_address, target_app)
Example #9
0
def test_receive_mediatedtransfer_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(HASH, ctx=GLOBAL_CTX, raw=True)
    other_address = privatekey_to_address(other_key.private_key)
    amount = 10
    locksroot = HASH
    mediated_transfer = MediatedTransfer(identifier=1,
                                         nonce=1,
                                         token=token_manager0.token_address,
                                         transferred_amount=amount,
                                         recipient=app0.raiden.address,
                                         locksroot=locksroot,
                                         lock=Lock(amount, 1, locksroot),
                                         target=privatekey_to_address(HASH2),
                                         initiator=other_address,
                                         fee=0)
    sign_and_send(mediated_transfer, other_key, other_address, app0)
Example #10
0
def test_receive_mediatedtransfer_unknown(raiden_network):
    app0 = raiden_network[0]  # pylint: disable=unbalanced-tuple-unpacking
    graph0 = app0.raiden.channelgraphs.values()[0]

    other_key = PrivateKey(HASH)
    other_address = privatekey_to_address(HASH)
    amount = 10
    locksroot = HASH
    mediated_transfer = MediatedTransfer(identifier=1,
                                         nonce=1,
                                         token=graph0.token_address,
                                         transferred_amount=amount,
                                         recipient=app0.raiden.address,
                                         locksroot=locksroot,
                                         lock=Lock(amount, 1, locksroot),
                                         target=privatekey_to_address(HASH2),
                                         initiator=other_address,
                                         fee=0)
    sign_and_send(mediated_transfer, other_key, other_address, app0)
def test_receive_mediatedtransfer_invalidrecipient(raiden_network,
                                                   token_addresses,
                                                   reveal_timeout, deposit):

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

    identifier = 1
    invalid_recipient = make_address()
    amount = 10
    expiration = reveal_timeout * 2
    mediated_transfer_message = MediatedTransfer(identifier=identifier,
                                                 nonce=1,
                                                 token=token_address,
                                                 channel=channel0.identifier,
                                                 transferred_amount=0,
                                                 recipient=invalid_recipient,
                                                 locksroot=UNIT_SECRETHASH,
                                                 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,
    )

    assert_synched_channel_state(
        token_address,
        app0,
        deposit,
        [],
        app1,
        deposit,
        [],
    )
Example #12
0
def test_mediated_transfer():
    nonce = balance = 1
    token = recipient = target = initiator = ADDRESS
    hashlock = locksroot = sha3(ADDRESS)
    amount = expiration = 1
    fee = 0

    lock = Lock(amount, expiration, hashlock)
    mediated_transfer = MediatedTransfer(
        1,  # TODO: fill in identifier
        nonce,
        token,
        balance,
        recipient,
        locksroot,
        lock,
        target,
        initiator,
        fee,
    )
    assert roundtrip_serialize_mediated_transfer(mediated_transfer)
Example #13
0
def test_receive_mediatedtransfer_unknown(raiden_network):
    app0 = raiden_network[0]  # pylint: disable=unbalanced-tuple-unpacking
    asset_manager0 = app0.raiden.managers_by_asset_address.values()[0]

    other_key = PrivateKey(sha3("rainstopped"), ctx=GLOBAL_CTX, raw=True)
    other_address = privatekey_to_address(other_key.private_key)
    amount = 10
    locksroot = sha3("muchsunny")
    mediated_transfer = MediatedTransfer(
        identifier=1,
        nonce=1,
        asset=asset_manager0.asset_address,
        transferred_amount=amount,
        recipient=app0.raiden.address,
        locksroot=locksroot,
        lock=Lock(amount, 1, locksroot),
        target=privatekey_to_address(sha3("cloudsagain")),
        initiator=other_address,
        fee=0
    )
    sign_and_send(mediated_transfer, other_key, other_address, app0)
Example #14
0
def make_mediated_transfer(identifier=0,
                           nonce=1,
                           token=ADDRESS,
                           transferred_amount=0,
                           amount=1,
                           expiration=1,
                           locksroot='',
                           recipient=ADDRESS,
                           target=ADDRESS,
                           initiator=ADDRESS,
                           fee=0):

    lock = make_lock(
        amount=amount,
        expiration=expiration,
    )

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

    return MediatedTransfer(identifier, nonce, token, transferred_amount,
                            recipient, locksroot, lock, target, initiator, fee)
Example #15
0
def test_receive_mediatedtransfer_invalid_address(raiden_chain,
                                                  token_addresses):
    app0, app1, app2 = raiden_chain
    token_address = token_addresses[0]

    amount = 10
    result = app0.raiden.mediated_transfer_async(
        token_address,
        amount,
        app2.raiden.address,
        identifier=1,
    )
    assert result.wait(timeout=10)

    # and now send one more mediated transfer with the same nonce, simulating
    # an out-of-order/resent message that arrives late
    channel0 = channel(app0, app1, token_address)
    lock = Lock(amount, 1, UNIT_HASHLOCK)
    identifier = create_default_identifier()
    mediated_transfer = MediatedTransfer(identifier=identifier,
                                         nonce=1,
                                         token=token_address,
                                         channel=channel0.channel_address,
                                         transferred_amount=amount,
                                         recipient=app1.raiden.address,
                                         locksroot=UNIT_HASHLOCK,
                                         lock=lock,
                                         target=app2.raiden.address,
                                         initiator=app0.raiden.address,
                                         fee=0)

    sign_and_send(
        mediated_transfer,
        app0.raiden.private_key,
        app0.raiden.address,
        app1,
    )
Example #16
0
def make_mediated_transfer(
        identifier=0,
        nonce=1,
        token=ADDRESS,
        transferred_amount=0,
        amount=1,
        locksroot='',
        recipient=ADDRESS,
        target=ADDRESS,
        initiator=ADDRESS,
        fee=0):

    return MediatedTransfer(
        identifier,
        nonce,
        token,
        transferred_amount,
        recipient,
        locksroot,
        make_lock_with_amount(amount),
        target,
        initiator,
        fee
    )
def test_decode_mediated_transfer(private_keys, settle_timeout, tester_state,
                                  tester_token, tester_events,
                                  tester_registry):

    privatekey0 = tester.DEFAULT_KEY
    privatekey1 = tester.k1
    privatekey2 = tester.k2
    address0 = privatekey_to_address(privatekey0)
    address1 = privatekey_to_address(privatekey1)
    address2 = privatekey_to_address(privatekey2)

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

    locksroot = sha3("Sikorka")
    amount = 1337
    expiration = 5
    lock = Lock(amount, expiration, locksroot)

    message = MediatedTransfer(identifier=313151,
                               nonce=88924902,
                               token=tester_token.address,
                               transferred_amount=amount,
                               recipient=address1,
                               locksroot=locksroot,
                               lock=lock,
                               target=address2,
                               initiator=address0)

    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() == 88924902
    assert dtester.decodedExpiration() == expiration
    assert dtester.decodedToken() == tester_token.address.encode('hex')
    assert dtester.decodedRecipient() == address1.encode('hex')
    assert dtester.decodedAmount() == amount
    assert dtester.decodedLocksroot() == locksroot
Example #18
0
def test_unlock_at_settlement_block(deposit, settle_timeout, reveal_timeout,
                                    tester_nettingcontracts, tester_state,
                                    tester_token):
    """ It must be possible to unlock a lock up to and including the settlment
    block.
    """

    pkey0, pkey1, nettingchannel = tester_nettingcontracts[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 + settle_timeout
    secret = 'settlementsettlementsettlementse'
    hashlock = sha3(secret)

    lock0 = Lock(
        amount=31,
        expiration=lock_expiration,
        hashlock=hashlock,
    )
    lock0_bytes = bytes(lock0.as_bytes)
    lock0_hash = sha3(lock0_bytes)

    opened_block = nettingchannel.opened(sender=pkey0)
    nonce = 1 + (opened_block * (2**32))

    mediated0 = MediatedTransfer(
        identifier=1,
        nonce=nonce,
        token=tester_token.address,
        transferred_amount=0,
        recipient=address1,
        locksroot=lock0_hash,
        lock=lock0,
        target=address1,
        initiator=address0,
        fee=0,
    )

    sign_key0 = PrivateKey(pkey0, ctx=GLOBAL_CTX, raw=True)
    mediated0.sign(sign_key0, address0)
    mediated0_data = str(mediated0.packed().data)
    nettingchannel.close(mediated0_data, sender=pkey1)

    block_until_settlement_end = lock_expiration - tester_state.block.number
    tester_state.mine(number_of_blocks=block_until_settlement_end)

    assert lock_expiration == tester_state.block.number
    nettingchannel.unlock(
        lock0_bytes,
        '',  # the lock itself it the root, the proof is empty
        secret,
        sender=pkey1,
    )

    tester_state.mine(number_of_blocks=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
Example #19
0
def test_receive_mediatedtransfer_invalid_address(raiden_network, private_keys):
    alice_app = raiden_network[0]
    messages = setup_messages_cb()

    graph = alice_app.raiden.channelgraphs.values()[0]
    token_address = graph.token_address

    mt_helper = MediatedTransferTestHelper(raiden_network, graph)
    initiator_address = alice_app.raiden.address
    path = mt_helper.get_paths_of_length(initiator_address, 2)

    alice_address, bob_address, charlie_address = path
    amount = 10
    result = alice_app.raiden.transfer_async(
        token_address,
        amount,
        charlie_address,
    )

    # check for invitation ping
    assert len(messages) == 2  # Ping, Ack
    ping_message = decode(messages[0])
    assert isinstance(ping_message, Ping)
    decoded = decode(messages[1])
    assert isinstance(decoded, Ack)
    assert decoded.echo == sha3(ping_message.encode() + charlie_address)

    assert result.wait(timeout=10)
    gevent.sleep(1.)

    # check that transfer messages were added
    assert len(messages) == 22  # Ping, Ack + tranfer messages
    # make sure that the mediated transfer is sent after the invitation ping
    assert isinstance(decode(messages[2]), MediatedTransfer)

    # and now send one more mediated transfer with the same nonce, simulating
    # an out-of-order/resent message that arrives late
    locksroot = HASH
    lock = Lock(amount, 1, locksroot)
    identifier = create_default_identifier(
        alice_app.raiden.address,
        graph.token_address,
        charlie_address,
    )
    mediated_transfer = MediatedTransfer(
        identifier=identifier,
        nonce=1,
        token=token_address,
        transferred_amount=amount,
        recipient=bob_address,
        locksroot=locksroot,
        lock=lock,
        target=charlie_address,
        initiator=initiator_address,
        fee=0
    )
    alice_key = PrivateKey(private_keys[0])
    target_app = None
    for app in raiden_network:
        if app.raiden.address not in path:
            target_app = app
            break
    sign_and_send(mediated_transfer, alice_key, alice_address, target_app)
Example #20
0
def test_receiver_cannot_spend_locked_amount():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    privkey2, address2 = make_privkey_address()

    balance1 = 33
    balance2 = 11

    reveal_timeout = 7
    settle_timeout = 21
    block_number = 7

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    amount1 = balance2
    expiration = block_number + settle_timeout
    receive_mediated_transfer0 = test_channel.create_mediatedtransfer(
        address1,
        address2,
        fee=0,
        amount=amount1,
        identifier=1,
        expiration=expiration,
        hashlock=sha3('test_locked_amount_cannot_be_spent'),
    )
    receive_mediated_transfer0.sign(privkey2, address2)

    test_channel.register_transfer(
        block_number,
        receive_mediated_transfer0,
    )

    # trying to send one unit of the locked token
    amount2 = balance1 + 1
    lock2 = Lock(
        amount=amount2,
        expiration=expiration,
        hashlock=sha3('test_locked_amount_cannot_be_spent2'),
    )
    layers = compute_layers([sha3(lock2.as_bytes)])
    tree2 = MerkleTreeState(layers)
    locksroot2 = merkleroot(tree2)

    send_mediated_transfer0 = MediatedTransfer(
        identifier=1,
        nonce=1,
        token=token_address,
        channel=test_channel.channel_address,
        transferred_amount=0,
        recipient=address2,
        locksroot=locksroot2,
        lock=lock2,
        target=address2,
        initiator=address1,
        fee=0,
    )
    send_mediated_transfer0.sign(privkey1, address1)

    # address1 balance is all locked
    with pytest.raises(InsufficientBalance):
        test_channel.register_transfer(
            block_number,
            send_mediated_transfer0,
        )
Example #21
0
def test_sender_cannot_overspend():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15
    block_number = 10

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    amount = balance1
    expiration = block_number + settle_timeout
    sent_mediated_transfer0 = test_channel.create_mediatedtransfer(
        address1,
        address2,
        fee=0,
        amount=amount,
        identifier=1,
        expiration=expiration,
        hashlock=sha3('test_locked_amount_cannot_be_spent'),
    )
    sent_mediated_transfer0.sign(privkey1, address1)

    test_channel.register_transfer(
        block_number,
        sent_mediated_transfer0,
    )

    lock2 = Lock(
        amount=amount,
        expiration=expiration,
        hashlock=sha3('test_locked_amount_cannot_be_spent2'),
    )
    leaves = [
        sha3(sent_mediated_transfer0.lock.as_bytes),
        sha3(lock2.as_bytes),
    ]
    tree2 = MerkleTreeState(compute_layers(leaves))
    locksroot2 = merkleroot(tree2)

    sent_mediated_transfer1 = MediatedTransfer(
        identifier=2,
        nonce=sent_mediated_transfer0.nonce + 1,
        token=token_address,
        channel=test_channel.channel_address,
        transferred_amount=0,
        recipient=address2,
        locksroot=locksroot2,
        lock=lock2,
        target=address2,
        initiator=address1,
        fee=0,
    )
    sent_mediated_transfer1.sign(privkey1, address1)

    # address1 balance is all locked
    with pytest.raises(InsufficientBalance):
        test_channel.register_transfer(
            block_number,
            sent_mediated_transfer1,
        )
Example #22
0
def make_mediated_transfer_with_fee(fee):
    return MediatedTransfer(0, 1, ADDRESS, 1, ADDRESS, "",
                            make_lock_with_amount(1), ADDRESS, ADDRESS, fee)
Example #23
0
def make_mediated_transfer_with_nonce(nonce):
    return MediatedTransfer(0, nonce, ADDRESS, 1, ADDRESS, "",
                            make_lock_with_amount(1), ADDRESS, ADDRESS, 0)
Example #24
0
def test_two_messages_mediated_transfer(state, token, channel, events):
    # test tokens and distribute tokens
    assert token.balanceOf(tester.a0) == 10000
    assert token.balanceOf(tester.a1) == 0
    assert token.transfer(tester.a1, 5000) is True
    assert token.balanceOf(tester.a0) == 5000
    assert token.balanceOf(tester.a1) == 5000

    # test global variables
    assert channel.settleTimeout() == 30
    assert channel.assetAddress() == token.address.encode('hex')
    assert channel.opened() == 0
    assert channel.closed() == 0
    assert channel.settled() == 0

    hashlock1 = sha3(tester.k0)
    lock_amount1 = 29
    lock_expiration1 = 31
    lock1 = Lock(lock_amount1, lock_expiration1, hashlock1)
    locksroot1 = merkleroot([
        sha3(lock1.as_bytes),
    ])

    hashlock2 = sha3(tester.k1)
    lock_amount2 = 29
    lock_expiration2 = 31
    lock2 = Lock(lock_amount2, lock_expiration2, hashlock2)
    locksroot2 = merkleroot([
        sha3(lock2.as_bytes),
    ])

    nonce = 1
    asset = token.address
    transfered_amount = 3
    recipient = tester.a2
    locksroot = locksroot1
    target = tester.a1
    initiator = tester.a0

    msg1 = MediatedTransfer(
        nonce,
        asset,
        transfered_amount,
        recipient,
        locksroot,
        lock1,
        target,
        initiator,
        fee=0,
    )
    msg1.sign(tester.k0)
    packed = msg1.packed()
    mediated_transfer1 = str(packed.data)

    nonce = 2
    asset = token.address
    transfered_amount = 4
    recipient = tester.a2
    locksroot = locksroot2
    target = tester.a0
    initiator = tester.a1

    msg2 = MediatedTransfer(
        nonce,
        asset,
        transfered_amount,
        recipient,
        locksroot,
        lock2,
        target,
        initiator,
        fee=0,
    )
    msg2.sign(tester.k1)
    packed = msg2.packed()
    mediated_transfer2 = str(packed.data)

    channel.close(mediated_transfer1, mediated_transfer2)

    # Test with message sender tester.a0
    assert channel.closed() == state.block.number
    assert channel.closingAddress() == tester.a0.encode('hex')
    # assert channel.participants(0)[10] == 1
    # assert channel.participants(0)[11] == token.address.encode('hex')
    # assert channel.participants(0)[9] == tester.a0.encode('hex')
    # assert channel.participants(0)[12] == tester.a1.encode('hex')
    # assert channel.participants(0)[3] == 1
    # assert channel.participants(0)[13] == locksroot1
    # assert channel.participants(0)[7] == '\x00' * 32

    # Test with message sender tester.a1
    assert channel.closed() == state.block.number
    assert channel.closingAddress() == tester.a0.encode('hex')
def test_sender_cannot_overspend():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15
    block_number = 10

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    amount = balance1
    expiration = block_number + settle_timeout
    sent_mediated_transfer0 = test_channel.create_mediatedtransfer(
        address1,
        address2,
        fee=0,
        amount=amount,
        identifier=1,
        expiration=expiration,
        hashlock=sha3(b'test_locked_amount_cannot_be_spent'),
    )
    sent_mediated_transfer0.sign(privkey1, address1)

    test_channel.register_transfer(
        block_number,
        sent_mediated_transfer0,
    )

    lock2 = Lock(
        amount=amount,
        expiration=expiration,
        hashlock=sha3(b'test_locked_amount_cannot_be_spent2'),
    )
    leaves = [
        sha3(sent_mediated_transfer0.lock.as_bytes),
        sha3(lock2.as_bytes),
    ]
    tree2 = MerkleTreeState(compute_layers(leaves))
    locksroot2 = merkleroot(tree2)

    sent_mediated_transfer1 = MediatedTransfer(
        identifier=2,
        nonce=sent_mediated_transfer0.nonce + 1,
        token=token_address,
        channel=test_channel.channel_address,
        transferred_amount=0,
        recipient=address2,
        locksroot=locksroot2,
        lock=lock2,
        target=address2,
        initiator=address1,
        fee=0,
    )
    sent_mediated_transfer1.sign(privkey1, address1)

    # address1 balance is all locked
    with pytest.raises(InsufficientBalance):
        test_channel.register_transfer(
            block_number,
            sent_mediated_transfer1,
        )
def test_withdraw_at_settlement_block(
        deposit,
        settle_timeout,
        tester_nettingcontracts,
        tester_chain,
        tester_token):

    """ It must be possible to unlock a lock up to and including the settlment
    block.
    """

    pkey0, pkey1, nettingchannel = tester_nettingcontracts[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_chain.block.number + settle_timeout
    secret = b'settlementsettlementsettlementse'
    hashlock = sha3(secret)

    lock0 = Lock(
        amount=lock_amount,
        expiration=lock_expiration,
        hashlock=hashlock,
    )
    lock0_bytes = bytes(lock0.as_bytes)
    lock0_hash = sha3(lock0_bytes)

    opened_block = nettingchannel.opened(sender=pkey0)
    nonce = 1 + (opened_block * (2 ** 32))

    mediated0 = MediatedTransfer(
        identifier=1,
        nonce=nonce,
        token=tester_token.address,
        channel=normalize_address(nettingchannel.address),
        transferred_amount=0,
        recipient=address1,
        locksroot=lock0_hash,
        lock=lock0,
        target=address1,
        initiator=address0,
        fee=0,
    )

    sign_key0 = PrivateKey(pkey0)
    mediated0.sign(sign_key0, address0)

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

    block_until_settlement_end = lock_expiration - tester_chain.block.number
    tester_chain.mine(number_of_blocks=block_until_settlement_end)

    assert lock_expiration == tester_chain.block.number
    nettingchannel.withdraw(
        lock0_bytes,
        b'',  # the lock itself it the root, the proof is empty
        secret,
        sender=pkey1,
    )

    tester_chain.mine(number_of_blocks=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
Example #27
0
def test_regression_multiple_revealsecret(raiden_network, token_addresses):
    """ Multiple RevealSecret messages arriving at the same time must be
    handled properly.

    Secret handling followed these steps:

        The Secret message arrives
        The secret is registered
        The channel is updated and the correspoding lock is removed
        * A balance proof for the new channel state is created and sent to the
          payer
        The channel is unregistered for the given secrethash

    The step marked with an asterisk above introduced a context-switch. This
    allowed a second Reveal Secret message to be handled before the channel was
    unregistered. And because the channel was already updated an exception was raised
    for an unknown secret.
    """
    app0, app1 = raiden_network
    token = token_addresses[0]
    channelstate_0_1 = get_channelstate(app0, app1, token)

    identifier = 1
    secret = sha3(b'test_regression_multiple_revealsecret')
    secrethash = sha3(secret)
    expiration = app0.raiden.get_block_number() + 100
    amount = 10
    lock = Lock(
        amount,
        expiration,
        secrethash,
    )

    nonce = 1
    transferred_amount = 0
    mediated_transfer = MediatedTransfer(
        identifier,
        nonce,
        token,
        channelstate_0_1.identifier,
        transferred_amount,
        app1.raiden.address,
        lock.secrethash,
        lock,
        app1.raiden.address,
        app0.raiden.address,
    )
    app0.raiden.sign(mediated_transfer)

    message_data = mediated_transfer.encode()
    app1.raiden.protocol.receive(message_data)

    reveal_secret = RevealSecret(secret)
    app0.raiden.sign(reveal_secret)
    reveal_secret_data = reveal_secret.encode()

    secret = Secret(
        identifier=identifier,
        nonce=mediated_transfer.nonce + 1,
        channel=channelstate_0_1.identifier,
        transferred_amount=amount,
        locksroot=EMPTY_MERKLE_ROOT,
        secret=secret,
    )
    app0.raiden.sign(secret)
    secret_data = secret.encode()

    messages = [
        secret_data,
        reveal_secret_data,
    ]

    wait = [
        gevent.spawn_later(
            .1,
            app1.raiden.protocol.receive,
            data,
        ) for data in messages
    ]

    gevent.joinall(wait)
Example #28
0
def make_mediated_transfer_with_amount(amount):
    return MediatedTransfer(0, 1, ADDRESS, amount, ADDRESS, "",
                            make_lock_with_amount(amount), ADDRESS, ADDRESS, 0)
def test_receiver_cannot_spend_locked_amount():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    privkey2, address2 = make_privkey_address()

    balance1 = 33
    balance2 = 11

    reveal_timeout = 7
    settle_timeout = 21
    block_number = 7

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    amount1 = balance2
    expiration = block_number + settle_timeout
    receive_mediated_transfer0 = test_channel.create_mediatedtransfer(
        address1,
        address2,
        fee=0,
        amount=amount1,
        identifier=1,
        expiration=expiration,
        hashlock=sha3(b'test_locked_amount_cannot_be_spent'),
    )
    receive_mediated_transfer0.sign(privkey2, address2)

    test_channel.register_transfer(
        block_number,
        receive_mediated_transfer0,
    )

    # trying to send one unit of the locked token
    amount2 = balance1 + 1
    lock2 = Lock(
        amount=amount2,
        expiration=expiration,
        hashlock=sha3(b'test_locked_amount_cannot_be_spent2'),
    )
    layers = compute_layers([sha3(lock2.as_bytes)])
    tree2 = MerkleTreeState(layers)
    locksroot2 = merkleroot(tree2)

    send_mediated_transfer0 = MediatedTransfer(
        identifier=1,
        nonce=1,
        token=token_address,
        channel=test_channel.channel_address,
        transferred_amount=0,
        recipient=address2,
        locksroot=locksroot2,
        lock=lock2,
        target=address2,
        initiator=address1,
        fee=0,
    )
    send_mediated_transfer0.sign(privkey1, address1)

    # address1 balance is all locked
    with pytest.raises(InsufficientBalance):
        test_channel.register_transfer(
            block_number,
            send_mediated_transfer0,
        )
Example #30
0
def test_update_mediated_transfer(state, token, channel, events):
    # test tokens and distribute tokens
    assert token.balanceOf(tester.a0) == 10000
    assert token.balanceOf(tester.a1) == 0
    assert token.transfer(tester.a1, 5000) is True
    assert token.balanceOf(tester.a0) == 5000
    assert token.balanceOf(tester.a1) == 5000

    # test global variables
    assert channel.settleTimeout() == 30
    assert channel.assetAddress() == token.address.encode('hex')
    assert channel.opened() == 0
    assert channel.closed() == 0
    assert channel.settled() == 0

    hashlock1 = sha3(tester.k0)
    lock_amount1 = 29
    lock_expiration1 = 31
    lock1 = Lock(lock_amount1, lock_expiration1, hashlock1)
    locksroot1 = merkleroot([
        sha3(lock1.as_bytes),
    ])

    hashlock2 = sha3(tester.k1)
    lock_amount2 = 29
    lock_expiration2 = 31
    lock2 = Lock(lock_amount2, lock_expiration2, hashlock2)
    locksroot2 = merkleroot([
        sha3(lock2.as_bytes),
    ])

    nonce = 1
    asset = token.address
    transfered_amount = 3
    recipient = tester.a2
    locksroot = locksroot1
    target = tester.a1
    initiator = tester.a0

    msg1 = MediatedTransfer(
        nonce,
        asset,
        transfered_amount,
        recipient,
        locksroot,
        lock1,
        target,
        initiator,
        fee=0,
    )
    msg1.sign(tester.k0)
    packed = msg1.packed()
    mediated_transfer1 = str(packed.data)

    nonce = 2
    asset = token.address
    transfered_amount = 4
    recipient = tester.a2
    locksroot = locksroot2
    target = tester.a0
    initiator = tester.a1

    msg2 = MediatedTransfer(
        nonce,
        asset,
        transfered_amount,
        recipient,
        locksroot,
        lock2,
        target,
        initiator,
        fee=0,
    )
    msg2.sign(tester.k1)
    packed = msg2.packed()
    mediated_transfer2 = str(packed.data)

    # not yet closed
    with pytest.raises(TransactionFailed):
        channel.updateTransfer(mediated_transfer1, sender=tester.k1)

    channel.close(mediated_transfer1, mediated_transfer2)

    # Test with message sender tester.a0
    assert channel.closed() == state.block.number
    assert channel.closingAddress() == tester.a0.encode('hex')
    # assert channel.participants(0)[10] == 1
    # assert channel.participants(0)[11] == token.address.encode('hex')
    # assert channel.participants(0)[9] == tester.a0.encode('hex')
    # assert channel.participants(0)[12] == tester.a1.encode('hex')
    # assert channel.participants(0)[3] == 1
    # assert channel.participants(0)[13] == locksroot1
    # assert channel.participants(0)[7] == '\x00' * 32

    # Test with message sender tester.a1
    assert channel.closed() == state.block.number
    assert channel.closingAddress() == tester.a0.encode('hex')
    # assert channel.participants(1)[10] == 2
    # assert channel.participants(1)[11] == token.address.encode('hex')
    # assert channel.participants(1)[9] == tester.a1.encode('hex')
    # assert channel.participants(1)[12] == tester.a0.encode('hex')
    # assert channel.participants(1)[3] == 3
    # assert channel.participants(1)[13] == locksroot2
    # assert channel.participants(1)[7] == '\x00' * 32

    hashlock3 = sha3(tester.k1)
    lock_amount3 = 29
    lock_expiration3 = 31
    lock3 = Lock(lock_amount3, lock_expiration3, hashlock3)
    locksroot3 = merkleroot([
        sha3(lock3.as_bytes),
    ])

    nonce = 3
    asset = token.address
    transfered_amount = 4
    recipient = tester.a2
    locksroot = locksroot3
    target = tester.a0
    initiator = tester.a1

    msg3 = MediatedTransfer(
        nonce,
        asset,
        transfered_amount,
        recipient,
        locksroot,
        lock3,
        target,
        initiator,
        fee=0,
    )
    msg3.sign(tester.k1)
    packed = msg3.packed()
    mediated_transfer3 = str(packed.data)
    # closingAddress == getSender(message)
    with pytest.raises(TransactionFailed):
        channel.updateTransfer(mediated_transfer1)

    channel.updateTransfer(mediated_transfer3, sender=tester.k1)

    # Test with message sender tester.a1
    # assert channel.participants(1)[10] == 3
    # assert channel.participants(1)[11] == token.address.encode('hex')
    # assert channel.participants(1)[9] == tester.a1.encode('hex')
    # assert channel.participants(1)[12] == tester.a0.encode('hex')
    # assert channel.participants(1)[3] == 5
    # assert channel.participants(1)[13] == locksroot3
    # assert channel.participants(1)[7] == '\x00' * 32

    msg4 = DirectTransfer(
        1,  # nonce
        token.address,  # asset
        5,  # transfered_amount
        tester.a0,  # recipient
        locksroot,
    )
    msg4.sign(tester.k1)
    packed = msg4.packed()
    direct_transfer4 = str(packed.data)

    # nonce too low
    with pytest.raises(TransactionFailed):
        channel.updateTransfer(direct_transfer4, sender=tester.k1)

    # settleTimeout overdue
    state.block.number = 1158041

    with pytest.raises(TransactionFailed):
        channel.updateTransfer(mediated_transfer3, sender=tester.k1)

    assert len(events) == 1
    assert events[0]['_event_type'] == 'ChannelClosed'
    assert events[0]['blockNumber'] == 1158002
    assert events[0]['closingAddress'] == tester.a0.encode('hex')
Example #31
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']
Example #32
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']