Exemplo n.º 1
0
def test_channel_cleared_after_our_unlock():
    pseudo_random_generator = random.Random()
    our_model, _ = create_model(balance=700, num_pending_locks=1)
    partner_model, partner_key1 = create_model(balance=700,
                                               num_pending_locks=0)
    channel_state = create_channel_from_models(our_model, partner_model,
                                               partner_key1)
    block_number = 1
    block_hash = make_block_hash()

    def make_unlock(unlock_end, partner_end):
        batch_unlock = ContractReceiveChannelBatchUnlock(
            transaction_hash=make_transaction_hash(),
            canonical_identifier=channel_state.canonical_identifier,
            receiver=partner_end.address,
            sender=unlock_end.address,
            locksroot=unlock_end.balance_proof.locksroot,
            unlocked_amount=10,
            returned_tokens=0,
            block_number=block_number,
            block_hash=block_hash,
        )
        return batch_unlock

    settle_channel = ContractReceiveChannelSettled(
        transaction_hash=make_transaction_hash(),
        canonical_identifier=channel_state.canonical_identifier,
        our_onchain_locksroot=compute_locksroot(
            channel_state.our_state.pending_locks),
        partner_onchain_locksroot=compute_locksroot(
            channel_state.partner_state.pending_locks),
        block_number=1,
        block_hash=make_block_hash(),
    )

    assert settle_channel.our_onchain_locksroot != LOCKSROOT_OF_NO_LOCKS
    assert settle_channel.partner_onchain_locksroot == LOCKSROOT_OF_NO_LOCKS

    iteration = channel.state_transition(
        channel_state=channel_state,
        state_change=settle_channel,
        block_number=block_number,
        block_hash=block_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    batch_unlock = make_unlock(channel_state.our_state,
                               channel_state.partner_state)
    iteration = channel.state_transition(
        channel_state=iteration.new_state,
        state_change=batch_unlock,
        block_number=block_number,
        block_hash=block_hash,
        pseudo_random_generator=pseudo_random_generator,
    )
    msg = "partner did not have any locks in the pending locks, channel should have been cleaned"
    assert iteration.new_state is None, msg
Exemplo n.º 2
0
 def update(self, amount, lock):
     self._pending_locks = channel.compute_locks_with(self._pending_locks, lock)
     if self.properties:
         self.properties = factories.replace(
             self.properties,
             locked_amount=self.properties.locked_amount + amount,
             locksroot=compute_locksroot(self._pending_locks),
             nonce=self.properties.nonce + 1,
         )
     else:
         self.properties = factories.BalanceProofProperties(
             transferred_amount=0,
             locked_amount=amount,
             nonce=1,
             locksroot=compute_locksroot(self._pending_locks),
             canonical_identifier=self._canonical_identifier,
         )
Exemplo n.º 3
0
def make_receive_expired_lock(
    channel_state: NettingChannelState,
    privkey: bytes,
    nonce: Nonce,
    transferred_amount: TokenAmount,
    lock: HashTimeLockState,
    locked_amount: LockedAmount,
    pending_locks: PendingLocksState = None,
    chain_id: ChainID = None,
) -> ReceiveLockExpired:

    typecheck(lock, HashTimeLockState)

    signer = LocalSigner(privkey)
    address = signer.address
    if address not in (channel_state.our_state.address,
                       channel_state.partner_state.address):
        raise ValueError("Private key does not match any of the participants.")

    if pending_locks is None:
        pending_locks = make_empty_pending_locks_state()
    else:
        assert lock.encoded not in pending_locks.locks

    locksroot = compute_locksroot(pending_locks)

    chain_id = chain_id or channel_state.chain_id
    lock_expired_msg = LockExpired(
        chain_id=chain_id,
        nonce=nonce,
        message_identifier=make_message_identifier(),
        transferred_amount=transferred_amount,
        locked_amount=TokenAmount(locked_amount),
        locksroot=locksroot,
        channel_identifier=channel_state.identifier,
        token_network_address=channel_state.token_network_address,
        recipient=channel_state.partner_state.address,
        secrethash=lock.secrethash,
        signature=EMPTY_SIGNATURE,
    )
    lock_expired_msg.sign(signer)

    balance_proof = balanceproof_from_envelope(lock_expired_msg)

    receive_lockedtransfer = ReceiveLockExpired(
        balance_proof=balance_proof,
        secrethash=lock.secrethash,
        message_identifier=make_message_identifier(),
        sender=balance_proof.sender,
    )

    return receive_lockedtransfer
Exemplo n.º 4
0
def test_mediator_clear_pairs_after_batch_unlock(chain_state,
                                                 token_network_state,
                                                 our_address,
                                                 channel_properties):
    """ Regression test for https://github.com/raiden-network/raiden/issues/2932
    The mediator must also clear the transfer pairs once a ReceiveBatchUnlock where
    he is a participant is received.
    """
    open_block_number = 10
    open_block_hash = factories.make_block_hash()

    pseudo_random_generator = random.Random()

    properties, pkey = channel_properties
    address = properties.partner_state.address
    channel_state = factories.create(properties)

    channel_new_state_change = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=channel_state,
        block_number=open_block_number,
        block_hash=open_block_hash,
    )

    channel_new_iteration = token_network.state_transition(
        token_network_state=token_network_state,
        state_change=channel_new_state_change,
        block_number=open_block_number,
        block_hash=open_block_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    lock_amount = 30
    lock_expiration = 20
    lock_secret = keccak(b"test_end_state")
    lock_secrethash = sha256(lock_secret).digest()
    lock = HashTimeLockState(lock_amount, lock_expiration, lock_secrethash)

    mediated_transfer = make_receive_transfer_mediated(
        channel_state=channel_state,
        privkey=pkey,
        nonce=1,
        transferred_amount=0,
        lock=lock)

    route_state = RouteState(
        route=[
            channel_state.our_state.address,
            channel_state.partner_state.address
        ],
        forward_channel_id=channel_state.canonical_identifier.
        channel_identifier,
    )
    from_hop = factories.make_hop_from_channel(channel_state)
    init_mediator = ActionInitMediator(
        route_states=[route_state],
        from_hop=from_hop,
        from_transfer=mediated_transfer,
        balance_proof=mediated_transfer.balance_proof,
        sender=mediated_transfer.balance_proof.sender,  # pylint: disable=no-member
    )

    node.state_transition(chain_state, init_mediator)

    closed_block_number = open_block_number + 10
    closed_block_hash = factories.make_block_hash()
    channel_close_state_change = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=channel_state.partner_state.address,
        canonical_identifier=channel_state.canonical_identifier,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    channel_closed_iteration = token_network.state_transition(
        token_network_state=channel_new_iteration.new_state,
        state_change=channel_close_state_change,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    settle_block_number = closed_block_number + channel_state.settle_timeout + 1
    channel_settled_state_change = ContractReceiveChannelSettled(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=channel_state.canonical_identifier,
        block_number=settle_block_number,
        block_hash=factories.make_block_hash(),
        our_onchain_locksroot=factories.make_32bytes(),
        partner_onchain_locksroot=LOCKSROOT_OF_NO_LOCKS,
    )

    channel_settled_iteration = token_network.state_transition(
        token_network_state=channel_closed_iteration.new_state,
        state_change=channel_settled_state_change,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    token_network_state_after_settle = channel_settled_iteration.new_state
    ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels
    assert len(ids_to_channels) == 1
    assert channel_state.identifier in ids_to_channels

    block_number = closed_block_number + 1
    channel_batch_unlock_state_change = ContractReceiveChannelBatchUnlock(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=channel_state.canonical_identifier,
        receiver=address,
        sender=our_address,
        locksroot=compute_locksroot(PendingLocksState([bytes(lock.encoded)])),
        unlocked_amount=lock_amount,
        returned_tokens=0,
        block_number=block_number,
        block_hash=factories.make_block_hash(),
    )
    channel_unlock_iteration = node.state_transition(
        chain_state=chain_state,
        state_change=channel_batch_unlock_state_change)
    chain_state = channel_unlock_iteration.new_state
    token_network_state = views.get_token_network_by_address(
        chain_state=chain_state,
        token_network_address=token_network_state.address)
    ids_to_channels = token_network_state.channelidentifiers_to_channels
    assert len(ids_to_channels) == 0

    # Make sure that all is fine in the next block
    block = Block(block_number=block_number + 1,
                  gas_limit=1,
                  block_hash=factories.make_transaction_hash())
    iteration = node.state_transition(chain_state=chain_state,
                                      state_change=block)
    assert iteration.new_state

    # Make sure that mediator task was cleared during the next block processing
    # since the channel was removed
    mediator_task = chain_state.payment_mapping.secrethashes_to_task.get(
        lock_secrethash)
    assert not mediator_task
Exemplo n.º 5
0
def test_channel_data_removed_after_unlock(chain_state, token_network_state,
                                           our_address, channel_properties):
    open_block_number = 10
    open_block_hash = factories.make_block_hash()

    pseudo_random_generator = random.Random()

    properties, pkey = channel_properties
    address = properties.partner_state.address
    channel_state = factories.create(properties)

    channel_new_state_change = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=channel_state,
        block_number=open_block_number,
        block_hash=open_block_hash,
    )

    channel_new_iteration = token_network.state_transition(
        token_network_state=token_network_state,
        state_change=channel_new_state_change,
        block_number=open_block_number,
        block_hash=open_block_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    lock_amount = 30
    lock_expiration = 20
    lock_secret = keccak(b"test_end_state")
    lock_secrethash = sha256(lock_secret).digest()
    lock = HashTimeLockState(lock_amount, lock_expiration, lock_secrethash)

    mediated_transfer = make_receive_transfer_mediated(
        channel_state=channel_state,
        privkey=pkey,
        nonce=1,
        transferred_amount=0,
        lock=lock)

    from_hop = factories.make_hop_from_channel(channel_state)
    init_target = ActionInitTarget(
        sender=mediated_transfer.balance_proof.sender,  # pylint: disable=no-member
        balance_proof=mediated_transfer.balance_proof,
        from_hop=from_hop,
        transfer=mediated_transfer,
    )

    node.state_transition(chain_state, init_target)

    closed_block_number = open_block_number + 10
    closed_block_hash = factories.make_block_hash()
    channel_close_state_change = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=channel_state.partner_state.address,
        canonical_identifier=channel_state.canonical_identifier,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    channel_closed_iteration = token_network.state_transition(
        token_network_state=channel_new_iteration.new_state,
        state_change=channel_close_state_change,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
        pseudo_random_generator=pseudo_random_generator,
    )
    channel_state_after_closed = channel_closed_iteration.new_state.channelidentifiers_to_channels[
        channel_state.identifier]

    settle_block_number = closed_block_number + channel_state.settle_timeout + 1
    channel_settled_state_change = ContractReceiveChannelSettled(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=channel_state.canonical_identifier,
        block_number=settle_block_number,
        block_hash=factories.make_block_hash(),
        our_onchain_locksroot=compute_locksroot(
            channel_state_after_closed.our_state.pending_locks),
        partner_onchain_locksroot=compute_locksroot(
            channel_state_after_closed.partner_state.pending_locks),
    )

    channel_settled_iteration = token_network.state_transition(
        token_network_state=channel_closed_iteration.new_state,
        state_change=channel_settled_state_change,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    token_network_state_after_settle = channel_settled_iteration.new_state
    ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels
    assert len(ids_to_channels) == 1
    assert channel_state.identifier in ids_to_channels

    unlock_blocknumber = settle_block_number + 5
    channel_batch_unlock_state_change = ContractReceiveChannelBatchUnlock(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=channel_state.canonical_identifier,
        receiver=our_address,
        sender=address,
        locksroot=compute_locksroot(PendingLocksState([bytes(lock.encoded)])),
        unlocked_amount=lock_amount,
        returned_tokens=0,
        block_number=closed_block_number + 1,
        block_hash=factories.make_block_hash(),
    )
    channel_unlock_iteration = token_network.state_transition(
        token_network_state=channel_settled_iteration.new_state,
        state_change=channel_batch_unlock_state_change,
        block_number=unlock_blocknumber,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    token_network_state_after_unlock = channel_unlock_iteration.new_state
    ids_to_channels = token_network_state_after_unlock.channelidentifiers_to_channels
    assert len(ids_to_channels) == 0
Exemplo n.º 6
0
def make_receive_transfer_mediated(
    channel_state: NettingChannelState,
    privkey: bytes,
    nonce: Nonce,
    transferred_amount: TokenAmount,
    lock: HashTimeLockState,
    pending_locks: PendingLocksState = None,
    locked_amount: Optional[PaymentWithFeeAmount] = None,
    chain_id: Optional[ChainID] = None,
) -> LockedTransferSignedState:

    typecheck(lock, HashTimeLockState)

    signer = LocalSigner(privkey)
    address = signer.address
    if address not in (channel_state.our_state.address,
                       channel_state.partner_state.address):
        raise ValueError("Private key does not match any of the participants.")

    if pending_locks is None:
        locks = make_empty_pending_locks_state()
        locks.locks.append(lock.encoded)
    else:
        assert bytes(lock.encoded) in pending_locks.locks
        locks = pending_locks

    if locked_amount is None:
        locked_amount = lock.amount

    assert locked_amount >= lock.amount

    locksroot = compute_locksroot(locks)

    payment_identifier = PaymentID(nonce)
    transfer_target = make_target_address()
    transfer_initiator = make_initiator_address()
    chain_id = chain_id or channel_state.chain_id

    transfer_metadata = Metadata(routes=[
        RouteMetadata(
            route=[channel_state.our_state.address,
                   Address(transfer_target)])
    ])

    mediated_transfer_msg = LockedTransfer(
        chain_id=chain_id,
        message_identifier=make_message_identifier(),
        payment_identifier=payment_identifier,
        nonce=nonce,
        token_network_address=channel_state.token_network_address,
        token=channel_state.token_address,
        channel_identifier=channel_state.identifier,
        transferred_amount=transferred_amount,
        locked_amount=TokenAmount(locked_amount),
        recipient=channel_state.partner_state.address,
        locksroot=locksroot,
        lock=Lock(amount=lock.amount,
                  expiration=lock.expiration,
                  secrethash=lock.secrethash),
        target=transfer_target,
        initiator=transfer_initiator,
        signature=EMPTY_SIGNATURE,
        fee=0,
        metadata=transfer_metadata,
    )
    mediated_transfer_msg.sign(signer)

    receive_lockedtransfer = LockedTransferSignedState(
        payment_identifier=payment_identifier,
        token=channel_state.token_address,
        lock=lock,
        initiator=transfer_initiator,
        target=transfer_target,
        message_identifier=make_message_identifier(),
        balance_proof=balanceproof_from_envelope(mediated_transfer_msg),
        routes=[
            route_metadata.route for route_metadata in transfer_metadata.routes
        ],
    )

    return receive_lockedtransfer
Exemplo n.º 7
0
def test_channel_cleared_after_two_unlocks():
    our_model, _ = create_model(balance=700, num_pending_locks=1)
    partner_model, partner_key1 = create_model(balance=700,
                                               num_pending_locks=1)
    channel_state = create_channel_from_models(our_model, partner_model,
                                               partner_key1)
    block_number = 1
    block_hash = make_block_hash()
    pseudo_random_generator = random.Random()

    def make_unlock(unlock_end, partner_end):
        batch_unlock = ContractReceiveChannelBatchUnlock(
            transaction_hash=make_transaction_hash(),
            canonical_identifier=channel_state.canonical_identifier,
            receiver=partner_end.address,
            sender=unlock_end.address,
            locksroot=unlock_end.balance_proof.locksroot,
            unlocked_amount=10,
            returned_tokens=0,
            block_number=block_number,
            block_hash=block_hash,
        )
        return batch_unlock

    settle_channel = ContractReceiveChannelSettled(
        transaction_hash=make_transaction_hash(),
        canonical_identifier=channel_state.canonical_identifier,
        our_onchain_locksroot=compute_locksroot(
            channel_state.our_state.pending_locks),
        partner_onchain_locksroot=compute_locksroot(
            channel_state.partner_state.pending_locks),
        block_number=1,
        block_hash=make_block_hash(),
    )
    iteration = channel.state_transition(
        channel_state=channel_state,
        state_change=settle_channel,
        block_number=block_number,
        block_hash=block_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    msg = "both participants have pending locks, locksroot must not represent the empty list"
    assert iteration.new_state.our_state.onchain_locksroot != LOCKSROOT_OF_NO_LOCKS, msg
    assert iteration.new_state.partner_state.onchain_locksroot != LOCKSROOT_OF_NO_LOCKS, msg

    batch_unlock = make_unlock(channel_state.our_state,
                               channel_state.partner_state)
    iteration = channel.state_transition(
        channel_state=iteration.new_state,
        state_change=batch_unlock,
        block_number=block_number,
        block_hash=block_hash,
        pseudo_random_generator=pseudo_random_generator,
    )
    msg = "all of our locks has been unlocked, onchain state must be updated"
    assert iteration.new_state.our_state.onchain_locksroot is LOCKSROOT_OF_NO_LOCKS, msg
    msg = "partner has pending locks, the locksroot must not represent the empty list"
    assert iteration.new_state.partner_state.onchain_locksroot is not LOCKSROOT_OF_NO_LOCKS, msg
    msg = "partner locksroot is not unlocked, channel should not have been cleaned"
    assert iteration.new_state is not None, msg

    # processing the same unlock twice must not count
    iteration = channel.state_transition(
        channel_state=iteration.new_state,
        state_change=batch_unlock,
        block_number=block_number,
        block_hash=block_hash,
        pseudo_random_generator=pseudo_random_generator,
    )
    msg = "partner has pending locks, the locksroot must not represent the empty list"
    assert iteration.new_state.partner_state.onchain_locksroot is not LOCKSROOT_OF_NO_LOCKS, msg
    msg = "partner locksroot is not unlocked, channel should not have been cleaned"
    assert iteration.new_state is not None, msg

    iteration = channel.state_transition(
        channel_state=iteration.new_state,
        state_change=make_unlock(channel_state.partner_state,
                                 channel_state.our_state),
        block_number=block_number,
        block_hash=block_hash,
        pseudo_random_generator=pseudo_random_generator,
    )
    msg = "all unlocks have been done, channel must be cleared"
    assert iteration.new_state is None, msg
Exemplo n.º 8
0
def test_empty():
    locks = PendingLocksState(list())
    assert compute_locksroot(locks) == LOCKSROOT_OF_NO_LOCKS