Ejemplo n.º 1
0
def test_events_for_balanceproof_lock_expired():
    """ The balance proof should not be sent if the lock has expird. """
    transfers_pair = make_transfers_pair(
        [factories.HOP1, factories.HOP2, factories.HOP3, factories.HOP4],
        factories.HOP6,
        amount=10,
        secret=factories.UNIT_SECRET,
    )

    last_pair = transfers_pair[-1]
    last_pair.payee_state = 'payee_secret_revealed'
    block_number = last_pair.payee_transfer.expiration + 1

    # the lock has expired, do not send a balance proof
    events = mediator.events_for_balanceproof(
        transfers_pair,
        block_number,
    )
    assert len(events) == 0

    middle_pair = transfers_pair[-2]
    middle_pair.payee_state = 'payee_secret_revealed'

    # Even though the last node did not receive the payment we should send the
    # balance proof to the middle node to avoid unnecessarely closing the
    # middle channel. This state should not be reached under normal operation,
    # the last hop needs to choose a proper reveal_timeout and must go on-chain
    # to withdraw the asset before the lock expires.
    events = mediator.events_for_balanceproof(
        transfers_pair,
        block_number,
    )
    assert len(events) == 1
    assert events[0].target == middle_pair.payee_route.node_address
    assert middle_pair.payee_state == 'payee_balance_proof'
Ejemplo n.º 2
0
def test_events_for_balanceproof_secret_unknown():
    """ Nothing to do if the secret is not known. """
    block_number = 1

    transfers_pair = make_transfers_pair(
        [factories.HOP1, factories.HOP2, factories.HOP3],
        factories.HOP6,
        amount=10,
    )

    # the secret is not known, so no event should be used
    events = mediator.events_for_balanceproof(
        transfers_pair,
        block_number,
    )
    assert len(events) == 0

    transfers_pair = make_transfers_pair(
        [factories.HOP1, factories.HOP2, factories.HOP3],
        factories.HOP6,
        amount=10,
        secret=factories.UNIT_SECRET,
    )

    # Even though the secret is set, there is not a single transfer pair with a
    # 'secret known' state, so nothing should be done. This state is impossible
    # to reach, in reality someone needs to reveal the secret to the mediator,
    # so at least one other node knows the secret.
    events = mediator.events_for_balanceproof(
        transfers_pair,
        block_number,
    )
    assert len(events) == 0
Ejemplo n.º 3
0
def test_events_for_balanceproof_middle_secret():
    """ Even though the secret should only propagate from the end of the chain
    to the front, if there is a payee node in the middle that knows the secret
    the Balance Proof is sent neverthless.

    This can be done safely because the secret is know to the mediator and
    there is reveal_timeout blocks to withdraw the lock on-chain with the payer.
    """
    transfers_pair = make_transfers_pair(
        [factories.HOP1, factories.HOP2, factories.HOP3, factories.HOP4],
        factories.HOP6,
        amount=10,
        secret=factories.UNIT_SECRET,
    )

    block_number = 1
    middle_pair = transfers_pair[1]
    middle_pair.payee_state = 'payee_secret_revealed'

    events = mediator.events_for_balanceproof(
        transfers_pair,
        block_number,
    )

    assert len(events) == 1
    assert events[0].target == middle_pair.payee_route.node_address
    assert middle_pair.payee_state == 'payee_balance_proof'
Ejemplo n.º 4
0
def test_events_for_balanceproof_channel_closed():
    """ Balance proofs are useless if the channel is closed/settled, the payee
    needs to go on-chain and use the latest known balance proof which includes
    this lock in the locksroot.
    """

    for invalid_state in ('closed', 'settled'):
        transfers_pair = make_transfers_pair(
            [factories.HOP1, factories.HOP2],
            factories.HOP6,
            amount=10,
            secret=factories.UNIT_SECRET,
        )

        block_number = 5
        last_pair = transfers_pair[-1]
        last_pair.payee_route.state = invalid_state
        last_pair.payee_route.close_block = block_number
        last_pair.payee_state = 'payee_secret_revealed'

        events = mediator.events_for_balanceproof(
            transfers_pair,
            block_number,
        )

        assert len(events) == 0
Ejemplo n.º 5
0
def test_events_for_balanceproof():
    """ Test the simple case were the last hop has learned the secret and sent
    to the mediator node.
    """
    transfers_pair = make_transfers_pair(
        [factories.HOP1, factories.HOP2],
        factories.HOP6,
        amount=10,
        secret=factories.UNIT_SECRET,
    )

    last_pair = transfers_pair[-1]
    last_pair.payee_state = 'payee_secret_revealed'

    # the lock has not expired yet
    block_number = last_pair.payee_transfer.expiration

    events = mediator.events_for_balanceproof(
        transfers_pair,
        block_number,
    )

    assert len(events) == 1
    assert events[0].target == last_pair.payee_route.node_address
    assert last_pair.payee_state == 'payee_balance_proof'
def test_events_for_balanceproof():
    """ Test the simple case were the last hop has learned the secret and sent
    to the mediator node.
    """
    transfers_pair = make_transfers_pair(
        factories.HOP1,
        [factories.HOP2, factories.HOP3],
        factories.HOP6,
        amount=10,
        secret=factories.UNIT_SECRET,
    )

    last_pair = transfers_pair[-1]
    last_pair.payee_state = 'payee_secret_revealed'

    # the lock has not expired yet
    block_number = last_pair.payee_transfer.expiration

    events = mediator.events_for_balanceproof(
        transfers_pair,
        block_number,
    )

    balance_proof = next(e for e in events if isinstance(e, SendBalanceProof))

    assert len(events) == 2
    assert any(isinstance(e, EventUnlockSuccess) for e in events)
    assert balance_proof.receiver == last_pair.payee_route.node_address
    assert last_pair.payee_state == 'payee_balance_proof'