Beispiel #1
0
def test_hub_lacks_funds(server_db):
    try:
        auth_wif = util.gen_funded_wif("XCP", 1000000, 1000000)
        client = Mph(util.MockAPI(auth_wif=auth_wif))
        client.connect(1000000, 65535, asset="XCP")
        cron.fund_deposits()
        assert False
    except err.InsufficientFunds:
        assert True
Beispiel #2
0
def connected_clients():

    # create asset
    unsigned_rawtx = api.create_issuance(
        source=FUNDING_ADDRESS,
        asset="A7736697071037023001",
        quantity=100000000
    )
    signed_rawtx = scripts.sign_deposit(
        get_txs, FUNDING_WIF, unsigned_rawtx
    )
    api.sendrawtransaction(tx_hex=signed_rawtx)

    # fund server
    for i in range(3):
        address = lib.get_funding_address()
        for asset in ["XCP", "A7736697071037023001"]:
            unsigned_rawtx = api.create_send(**{
                'source': FUNDING_ADDRESS,
                'destination': address,
                'asset': asset,
                'quantity': 1000000,
                'regular_dust_size': 1000000
            })
            signed_rawtx = scripts.sign_deposit(
                get_txs, FUNDING_WIF, unsigned_rawtx
            )
            api.sendrawtransaction(tx_hex=signed_rawtx)

    # connect clients
    clients = []

    # fund XCP clients
    for i in range(3):
        wif = util.gen_funded_wif("XCP", 1000000, 1000000)
        client = Mph(util.MockAPI(auth_wif=wif))
        client.connect(1000000, expire_time=42, asset="XCP")
        clients.append(client)

    # fund A7736697071037023001 clients
    for i in range(3):
        wif = util.gen_funded_wif("A7736697071037023001", 1000000, 1000000)
        client = Mph(util.MockAPI(auth_wif=wif))
        client.connect(1000000, expire_time=42, asset="A7736697071037023001")
        clients.append(client)

    cron.fund_deposits()

    return clients
Beispiel #3
0
def connect(asset, quantity, expire_time=1024, delay_time=2):
    """ Create micropayment connection with hub.

    Args:
        asset (str): Asset to exchange in connection.
        quantity (str): Quantity to be bound in the deposit, this determins
                        the maximum amount that can bet transferred.
        expire_time (int, default=1024): Time in blocks after which the
                                         deposit expires and can be recovered.
        delay_time (int, default=2): Blocks hub must wait before payout,
                                     protects against publish revoked commits.

    Returns:
        {
            "send_deposit_txid": "published bitcoin transaction id",
            "handle": "handle for created connection"
        }
    """

    # connect to hub
    client = Mph(_hub_api())
    send_deposit_txid = client.connect(quantity,
                                       expire_time=expire_time,
                                       asset=asset,
                                       delay_time=delay_time)

    # save to data
    data = _load_data()
    data["connections"][client.handle] = client.serialize()
    _save_data(data)

    return {"send_deposit_txid": send_deposit_txid, "handle": client.handle}
Beispiel #4
0
def test_simulation_xcp():

    # fund server
    for i in range(2):
        address = lib.get_funding_addresses([ASSET])[ASSET]
        rawtx = api.create_send(**{
            'source': FUNDING_ADDRESS,
            'destination': address,
            'asset': ASSET,
            'quantity': 1000000,
            'regular_dust_size': 1000000
        })
        api.sendrawtransaction(tx_hex=rawtx)

    # connect clients
    clients = []
    for i in range(2):
        bob_wif = util.gen_funded_wif(ASSET, 1000000, 1000000)
        client = Mph(util.MockAPI(auth_wif=bob_wif))
        txid = client.connect(1000000, 65535, asset=ASSET)
        assert txid is not None

        status = client.get_status()
        assert status["send_balance"] == 1000000
        assert status["send_deposit_ttl"] is not None
        assert status["recv_deposit_ttl"] is None  # hub deposit not yet made

        clients.append(client)

    # server funds deposits
    cron.run_all()
    for client in clients:
        status = client.get_status()
        assert status["recv_deposit_ttl"] is not None  # hub deposit now made
Beispiel #5
0
def connected_clients():

    # create asset
    rawtx = api.create_issuance(source=FUNDING_ADDRESS,
                                asset="A7736697071037023001",
                                quantity=100000000)
    api.sendrawtransaction(tx_hex=rawtx)

    # fund server
    for i in range(3):
        addresses = lib.get_funding_addresses(["XCP", "A7736697071037023001"])
        for asset, address in addresses.items():
            rawtx = api.create_send(
                **{
                    'source': FUNDING_ADDRESS,
                    'destination': address,
                    'asset': asset,
                    'quantity': 1000000,
                    'regular_dust_size': 1000000
                })
            api.sendrawtransaction(tx_hex=rawtx)

    # connect clients
    clients = []

    # fund XCP clients
    for i in range(3):
        bob_wif = util.gen_funded_wif("XCP", 1000000, 1000000)
        client = Mph(util.MockAPI(auth_wif=bob_wif))
        client.connect(1000000, 42, asset="XCP")
        clients.append(client)

    # fund A7736697071037023001 clients
    for i in range(3):
        bob_wif = util.gen_funded_wif("A7736697071037023001", 1000000, 1000000)
        client = Mph(util.MockAPI(auth_wif=bob_wif))
        client.connect(1000000, 42, asset="A7736697071037023001")
        clients.append(client)

    cron.fund_deposits()

    return clients
Beispiel #6
0
def connect(asset, quantity, expire_time=1024, delay_time=2):
    """ Create micropayment connection with hub.

    Args:
        asset (str): Asset to exchange in connection.
        quantity (str): Quantity to be bound in the deposit, this determins
                        the maximum amount that can bet transferred.
        expire_time (int, default=1024): Time in blocks after which the
                                         deposit expires and can be recovered.
        delay_time (int, default=2): Blocks hub must wait before payout,
                                     protects against publish revoked commits.

    Returns:
        {
            "send_deposit_txid": "published bitcoin transaction id",
            "handle": "handle for created connection"
        }
    """

    # check if funds available
    _status = status()
    _quantity = _status["wallet"]["balances"].get(asset, 0)
    err_msg = "Insufficient {0}: {1} required, {2} available!"
    assert _quantity > quantity, err_msg.format(asset, quantity, _quantity)

    # connect to hub
    client = Mph(_hub_api())
    send_deposit_txid = client.connect(quantity, expire_time=expire_time,
                                       asset=asset, delay_time=delay_time)

    # save to data
    data = _load_data()
    data["connections"][client.handle] = client.serialize()
    _save_data(data)

    return {
        "send_deposit_txid": send_deposit_txid,
        "handle": client.handle
    }
Beispiel #7
0
def test_simulation_xcp():

    # fund server
    for i in range(2):
        address = lib.get_funding_address()
        unsigned_rawtx = api.create_send(**{
            'source': FUNDING_ADDRESS,
            'destination': address,
            'asset': ASSET,
            'quantity': 1000000,
            'regular_dust_size': 1000000
        })
        signed_rawtx = scripts.sign_deposit(
            get_txs, FUNDING_WIF, unsigned_rawtx)
        api.sendrawtransaction(tx_hex=signed_rawtx)

    # connect clients
    clients = []
    for i in range(2):
        bob_wif = util.gen_funded_wif(ASSET, 1000000, 1000000)
        client = Mph(util.MockAPI(auth_wif=bob_wif))
        txid = client.connect(1000000, 65535, asset=ASSET)
        assert txid is not None

        status = client.get_status()
        assert status["send_balance"] == 1000000
        assert status["send_deposit_ttl"] is not None
        assert status["recv_deposit_ttl"] is None  # hub deposit not yet made

        clients.append(client)

    # server funds deposits
    cron.run_all()
    for client in clients:
        status = client.get_status()
        assert status["recv_deposit_ttl"] is not None  # hub deposit now made
def test_standard_usage(server_db):

    # fund server
    for i in range(4):
        address = lib.get_funding_address()
        unsigned_rawtx = api.create_send(**{
            'source': FUNDING_ADDRESS,
            'destination': address,
            'asset': ASSET,
            'quantity': 1000000,
            'regular_dust_size': 1000000
        })
        signed_rawtx = scripts.sign_deposit(
            get_txs, FUNDING_WIF, unsigned_rawtx
        )
        api.sendrawtransaction(tx_hex=signed_rawtx)

    # connect clients
    status = api.mph_status()
    assert len(status["connections"]) == 0
    clients = []
    for i in range(4):
        auth_wif = util.gen_funded_wif(ASSET, 1000000, 1000000)
        client = Mph(util.MockAPI(auth_wif=auth_wif))
        txid = client.connect(1000000, 42, asset=ASSET)
        assert txid is not None

        status = client.get_status()
        assert status["send_balance"] == 1000000
        assert status["send_deposit_ttl"] is not None
        assert status["recv_deposit_ttl"] is None  # hub deposit not yet made
        clients.append(client)
    assert len(api.mph_status()["connections"]) == 4

    # server funds deposits
    assert len(cron.fund_deposits()) == 4
    assert len(cron.fund_deposits()) == 0
    for client in clients:
        status = client.get_status()
        assert status["recv_deposit_ttl"] is not None  # hub deposit now made

    # before status
    alpha, beta, gamma, delta = clients
    alpha_before_status = alpha.get_status()
    beta_before_status = beta.get_status()
    gamma_before_status = gamma.get_status()

    # can send multiple payments
    alpha.micro_send(beta.handle, 5, "0000")
    alpha.micro_send(gamma.handle, 6, "0001")
    assert alpha.sync() == []
    assert beta.sync() == [{
        "payer_handle": alpha.handle,
        "amount": 5,
        "token": "0000"
    }]
    assert gamma.sync(), [{
        "payer_handle": alpha.handle,
        "amount": 6,
        "token": "0001"
    }]

    # send more back, commits are revoked to maximize liquidity
    beta.micro_send(alpha.handle, 42, "0003")
    assert beta.sync() == []
    assert alpha.sync() == [{
        "payer_handle": beta.handle,
        "amount": 42,
        "token": "0003"
    }]

    # multiple syncs/commtis from single client
    alpha.micro_send(beta.handle, 1, "0004")
    assert alpha.sync() == []

    # get after status
    alpha_after_status = alpha.get_status()
    beta_after_status = beta.get_status()
    gamma_after_status = gamma.get_status()

    # compare statuses
    alpha_after_status["send_balance"] == alpha_before_status[
        "send_balance"] + 27
    beta_after_status["send_balance"] == beta_before_status[
        "send_balance"] - 40
    gamma_after_status["send_balance"] == gamma_before_status[
        "send_balance"] + 5

    # client | c2h active | h2c active
    # -------+------------+-----------
    # alpha  | 1 commit   | 1 commit
    # beta   | 1 commit   | 0 commit
    # gamma  | 0 commit   | 1 commit
    # delta  | 0 commit   | 0 commit
    assert len(alpha.c2h_state["commits_active"]) == 1
    assert len(alpha.h2c_state["commits_active"]) == 1
    assert len(beta.c2h_state["commits_active"]) == 1
    assert len(beta.h2c_state["commits_active"]) == 0
    assert len(gamma.c2h_state["commits_active"]) == 0
    assert len(gamma.h2c_state["commits_active"]) == 1
    assert len(delta.c2h_state["commits_active"]) == 0
    assert len(delta.h2c_state["commits_active"]) == 0

    # close alpha payment channel
    #        | h2c | c2h |
    # -------+-----+-----+
    # commit |  X  |  X  |
    # payout |  X  |  X  |
    # change |  X  |  X  |
    assert len(api.mph_status()["connections"]) == 4
    assert alpha.close() is not None        # H2C COMMIT TX
    assert len(api.mph_status()["connections"]) == 3
    assert _check_rawtxs(alpha.update())  # h2c payout delay not yet passed
    util_test.create_next_block(server_db)  # let payout delay pass
    assert _check_rawtxs(alpha.update(), payout=1)  # H2C PAYOUT TX

    # H2C CHANGE TX, C2H COMMIT TX
    assert _check_rawtxs(cron.run_all(), change=1, commit=1)

    util_test.create_next_block(server_db)  # let c2h payout delay pass
    assert _check_rawtxs(cron.run_all(), payout=1)  # C2H PAYOUT TX
    assert _check_rawtxs(alpha.update(), change=1)  # C2H CHANGE TX

    # close beta payment channel
    # recover | h2c | c2h |
    # --------+-----+-----+
    # commit  |  -  |  X  |
    # payout  |  -  |  X  |
    # change  |  X  |  X  |
    assert len(api.mph_status()["connections"]) == 3
    assert beta.close() is None
    assert len(api.mph_status()["connections"]) == 2
    # H2C CHANGE TX, C2H COMMIT TX
    assert _check_rawtxs(cron.run_all(), change=1, commit=1)
    util_test.create_next_block(server_db)  # let payout delay pass
    assert _check_rawtxs(cron.run_all(), payout=1)  # C2H PAYOUT TX
    assert _check_rawtxs(beta.update(), change=1)  # C2H CHANGE TX

    # close gamma payment channel
    # recover | h2c | c2h |
    # --------+-----+-----+
    # commit  |  X  |  -  |
    # payout  |  X  |  -  |
    # change  |  X  |  X  |
    assert len(api.mph_status()["connections"]) == 2
    assert gamma.close() is not None        # H2C COMMIT TX
    assert len(api.mph_status()["connections"]) == 1
    assert _check_rawtxs(gamma.update(), change=1)  # C2H CHANGE TX
    assert _check_rawtxs(gamma.update(), payout=1)  # H2C PAYOUT TX
    assert _check_rawtxs(cron.run_all(), change=1)  # H2C CHANGE TX

    # close delta payment channel
    # recover | h2c | c2h |
    # --------+-----+-----+
    # commit  |  -  |  -  |
    # payout  |  -  |  -  |
    # change  |  X  |  X  |
    assert len(api.mph_status()["connections"]) == 1
    assert delta.close() is None
    assert len(api.mph_status()["connections"]) == 0
    assert _check_rawtxs(delta.update(), change=1)  # C2H CHANGE TX
    assert _check_rawtxs(cron.run_all(), change=1)  # H2C CHANGE TX

    _assert_states_synced(alpha.handle, alpha.c2h_state, alpha.h2c_state)
    _assert_states_synced(beta.handle, beta.c2h_state, beta.h2c_state)
    _assert_states_synced(gamma.handle, gamma.c2h_state, gamma.h2c_state)
    _assert_states_synced(delta.handle, delta.c2h_state, delta.h2c_state)
def test_user_doesnt_publish_commit(server_db):

    # fund server
    for i in range(2):
        address = lib.get_funding_address()
        unsigned_rawtx = api.create_send(**{
            'source': FUNDING_ADDRESS,
            'destination': address,
            'asset': ASSET,
            'quantity': 1000000,
            'regular_dust_size': 1000000
        })
        signed_rawtx = scripts.sign_deposit(get_txs, FUNDING_WIF,
                                            unsigned_rawtx)
        api.sendrawtransaction(tx_hex=signed_rawtx)

    # connect clients
    assert len(api.mph_status()["connections"]) == 0
    clients = []
    for i in range(2):
        auth_wif = util.gen_funded_wif(ASSET, 1000000, 1000000)
        client = Mph(util.MockAPI(auth_wif=auth_wif))
        txid = client.connect(1000000, 42, asset=ASSET)
        assert txid is not None

        status = client.get_status()
        assert status["send_balance"] == 1000000
        assert status["send_deposit_ttl"] is not None
        assert status["recv_deposit_ttl"] is None  # hub deposit not yet made
        clients.append(client)
    assert len(api.mph_status()["connections"]) == 2

    # server funds deposits
    assert len(cron.fund_deposits()) == 2
    assert len(cron.fund_deposits()) == 0
    for client in clients:
        status = client.get_status()
        assert status["recv_deposit_ttl"] is not None  # hub deposit now made

    # before status
    alpha, beta = clients

    # send funds to beta
    alpha.micro_send(beta.handle, 42)
    alpha.sync()
    alpha_status = alpha.get_status()
    assert alpha_status["send_balance"] == 1000000 - 42 - 1

    # beta received funds
    beta.sync()
    beta_status = beta.get_status()
    assert beta_status["send_balance"] == 1000000 + 42 - 1

    # return some funds to alpha
    beta.micro_send(alpha.handle, 13)
    beta.sync()
    beta_status = beta.get_status()
    assert beta_status["send_balance"] == 1000000 + 42 - 1 - 13 - 1

    # alpha received funds
    alpha.sync()
    alpha_status = alpha.get_status()
    assert alpha_status["send_balance"] == 1000000 - 42 - 1 + 13 - 1

    # beta settles
    assert len(api.mph_status()["connections"]) == 2
    assert beta.close() is not None  # H2C COMMIT TX
    assert len(api.mph_status()["connections"]) == 1
    assert _check_rawtxs(beta.update())  # h2c payout delay not yet passed
    util_test.create_next_block(server_db)  # let payout delay pass
    assert _check_rawtxs(beta.update(), payout=1)  # H2C PAYOUT TX
    # H2C CHANGE TX, C2H COMMIT TX
    assert _check_rawtxs(cron.run_all(), change=1, commit=1)
    util_test.create_next_block(server_db)  # let c2h payout delay pass
    assert _check_rawtxs(cron.run_all(), payout=1)  # C2H PAYOUT TX
    assert _check_rawtxs(beta.update(), change=1)  # C2H CHANGE TX

    # let channel expire
    for i in range(50):
        util_test.create_next_block(server_db)

    # hub closes alice channel
    #        | h2c | c2h |
    # -------+-----+-----+
    # commit |  -  |  X  |
    # payout |  -  |  X  |
    # change |  -  |  -  |
    # expire |  X  |  -  |
    # C2H COMMIT TX, H2C EXPIRE TX
    assert _check_rawtxs(cron.run_all(), commit=1, expire=1)
    assert _check_rawtxs(cron.run_all(), payout=1)  # C2H PAYOUT TX
Beispiel #10
0
def test_standard_usage(server_db):

    # fund server
    for i in range(4):
        address = lib.get_funding_address()
        unsigned_rawtx = api.create_send(**{
            'source': FUNDING_ADDRESS,
            'destination': address,
            'asset': ASSET,
            'quantity': 1000000,
            'regular_dust_size': 1000000
        })
        signed_rawtx = scripts.sign_deposit(
            get_txs, FUNDING_WIF, unsigned_rawtx
        )
        api.sendrawtransaction(tx_hex=signed_rawtx)

    # connect clients
    assert len(api.mph_status()["connections"]) == 0
    clients = []
    for i in range(4):
        auth_wif = util.gen_funded_wif(ASSET, 1000000, 1000000)
        client = Mph(util.MockAPI(auth_wif=auth_wif))
        txid = client.connect(1000000, 42, asset=ASSET)
        assert txid is not None

        status = client.get_status()
        assert status["send_balance"] == 1000000
        assert status["send_deposit_ttl"] is not None
        assert status["recv_deposit_ttl"] is None  # hub deposit not yet made
        clients.append(client)
    assert len(api.mph_status()["connections"]) == 4

    # server funds deposits
    assert len(cron.fund_deposits()) == 4
    assert len(cron.fund_deposits()) == 0
    for client in clients:
        status = client.get_status()
        assert status["recv_deposit_ttl"] is not None  # hub deposit now made

    # before status
    alpha, beta, gamma, delta = clients
    alpha_before_status = alpha.get_status()
    beta_before_status = beta.get_status()
    gamma_before_status = gamma.get_status()

    # can send multiple payments
    alpha.micro_send(beta.handle, 5, "0000")
    alpha.micro_send(gamma.handle, 6, "0001")
    assert alpha.sync() == []
    assert beta.sync() == [{
        "payer_handle": alpha.handle,
        "amount": 5,
        "token": "0000"
    }]
    assert gamma.sync(), [{
        "payer_handle": alpha.handle,
        "amount": 6,
        "token": "0001"
    }]

    # send more back, commits are revoked to maximize liquidity
    beta.micro_send(alpha.handle, 42, "0003")
    assert beta.sync() == []
    assert alpha.sync() == [{
        "payer_handle": beta.handle,
        "amount": 42,
        "token": "0003"
    }]

    # multiple syncs/commtis from single client
    alpha.micro_send(beta.handle, 1, "0004")
    assert alpha.sync() == []

    # get after status
    alpha_after_status = alpha.get_status()
    beta_after_status = beta.get_status()
    gamma_after_status = gamma.get_status()

    # compare statuses
    alpha_after_status["send_balance"] == alpha_before_status[
        "send_balance"] + 27
    beta_after_status["send_balance"] == beta_before_status[
        "send_balance"] - 40
    gamma_after_status["send_balance"] == gamma_before_status[
        "send_balance"] + 5

    # client | c2h active | h2c active
    # -------+------------+-----------
    # alpha  | 1 commit   | 1 commit
    # beta   | 1 commit   | 0 commit
    # gamma  | 0 commit   | 1 commit
    # delta  | 0 commit   | 0 commit
    assert len(alpha.c2h_state["commits_active"]) == 1
    assert len(alpha.h2c_state["commits_active"]) == 1
    assert len(beta.c2h_state["commits_active"]) == 1
    assert len(beta.h2c_state["commits_active"]) == 0
    assert len(gamma.c2h_state["commits_active"]) == 0
    assert len(gamma.h2c_state["commits_active"]) == 1
    assert len(delta.c2h_state["commits_active"]) == 0
    assert len(delta.h2c_state["commits_active"]) == 0
Beispiel #11
0
def test_standard_usage(server_db):

    # fund server
    for i in range(4):
        address = lib.get_funding_addresses([ASSET])[ASSET]
        unsigned_rawtx = api.create_send(
            **{
                'source': FUNDING_ADDRESS,
                'destination': address,
                'asset': ASSET,
                'quantity': 1000000,
                'regular_dust_size': 1000000
            })
        signed_rawtx = scripts.sign_deposit(get_tx, FUNDING_WIF,
                                            unsigned_rawtx)
        api.sendrawtransaction(tx_hex=signed_rawtx)

    # connect clients
    assert len(api.mph_status()["connections"]) == 0
    clients = []
    for i in range(4):
        auth_wif = util.gen_funded_wif(ASSET, 1000000, 1000000)
        client = Mph(util.MockAPI(auth_wif=auth_wif))
        txid = client.connect(1000000, 42, asset=ASSET)
        assert txid is not None

        status = client.get_status()
        assert status["send_balance"] == 1000000
        assert status["send_deposit_ttl"] is not None
        assert status["recv_deposit_ttl"] is None  # hub deposit not yet made
        clients.append(client)
    assert len(api.mph_status()["connections"]) == 4

    # server funds deposits
    assert len(cron.fund_deposits()) == 4
    assert len(cron.fund_deposits()) == 0
    for client in clients:
        status = client.get_status()
        assert status["recv_deposit_ttl"] is not None  # hub deposit now made

    # before status
    alpha, beta, gamma, delta = clients
    alpha_before_status = alpha.get_status()
    beta_before_status = beta.get_status()
    gamma_before_status = gamma.get_status()

    # can send multiple payments
    alpha.micro_send(beta.handle, 5, "0000")
    alpha.micro_send(gamma.handle, 6, "0001")
    assert alpha.sync() == []
    assert beta.sync() == [{
        "payer_handle": alpha.handle,
        "amount": 5,
        "token": "0000"
    }]
    assert gamma.sync(), [{
        "payer_handle": alpha.handle,
        "amount": 6,
        "token": "0001"
    }]

    # send more back, commits are revoked to maximize liquidity
    beta.micro_send(alpha.handle, 42, "0003")
    assert beta.sync() == []
    assert alpha.sync() == [{
        "payer_handle": beta.handle,
        "amount": 42,
        "token": "0003"
    }]

    # multiple syncs/commtis from single client
    alpha.micro_send(beta.handle, 1, "0004")
    assert alpha.sync() == []

    # get after status
    alpha_after_status = alpha.get_status()
    beta_after_status = beta.get_status()
    gamma_after_status = gamma.get_status()

    # compare statuses
    alpha_after_status[
        "send_balance"] == alpha_before_status["send_balance"] + 27
    beta_after_status[
        "send_balance"] == beta_before_status["send_balance"] - 40
    gamma_after_status[
        "send_balance"] == gamma_before_status["send_balance"] + 5

    # client | c2h active | h2c active
    # -------+------------+-----------
    # alpha  | 1 commit   | 1 commit
    # beta   | 1 commit   | 0 commit
    # gamma  | 0 commit   | 1 commit
    # delta  | 0 commit   | 0 commit
    assert len(alpha.c2h_state["commits_active"]) == 1
    assert len(alpha.h2c_state["commits_active"]) == 1
    assert len(beta.c2h_state["commits_active"]) == 1
    assert len(beta.h2c_state["commits_active"]) == 0
    assert len(gamma.c2h_state["commits_active"]) == 0
    assert len(gamma.h2c_state["commits_active"]) == 1
    assert len(delta.c2h_state["commits_active"]) == 0
    assert len(delta.h2c_state["commits_active"]) == 0

    # close alpha payment channel
    #        | h2c | c2h |
    # -------+-----+-----+
    # commit |  X  |  X  |
    # payout |  X  |  X  |
    # change |  X  |  X  |
    assert len(api.mph_status()["connections"]) == 4
    assert alpha.close() is not None  # H2C COMMIT TX
    assert len(api.mph_status()["connections"]) == 3
    assert _check_rawtxs(alpha.update())  # h2c payout delay not yet passed
    util_test.create_next_block(server_db)  # let payout delay pass
    assert _check_rawtxs(alpha.update(), payout=1)  # H2C PAYOUT TX

    # H2C CHANGE TX, C2H COMMIT TX
    assert _check_rawtxs(cron.run_all(), change=1, commit=1)

    util_test.create_next_block(server_db)  # let c2h payout delay pass
    assert _check_rawtxs(cron.run_all(), payout=1)  # C2H PAYOUT TX
    assert _check_rawtxs(alpha.update(), change=1)  # C2H CHANGE TX

    # close beta payment channel
    # recover | h2c | c2h |
    # --------+-----+-----+
    # commit  |  -  |  X  |
    # payout  |  -  |  X  |
    # change  |  X  |  X  |
    assert len(api.mph_status()["connections"]) == 3
    assert beta.close() is None
    assert len(api.mph_status()["connections"]) == 2
    # H2C CHANGE TX, C2H COMMIT TX
    assert _check_rawtxs(cron.run_all(), change=1, commit=1)
    util_test.create_next_block(server_db)  # let payout delay pass
    assert _check_rawtxs(cron.run_all(), payout=1)  # C2H PAYOUT TX
    assert _check_rawtxs(beta.update(), change=1)  # C2H CHANGE TX

    # close gamma payment channel
    # recover | h2c | c2h |
    # --------+-----+-----+
    # commit  |  X  |  -  |
    # payout  |  X  |  -  |
    # change  |  X  |  X  |
    assert len(api.mph_status()["connections"]) == 2
    assert gamma.close() is not None  # H2C COMMIT TX
    assert len(api.mph_status()["connections"]) == 1
    assert _check_rawtxs(gamma.update(), change=1)  # C2H CHANGE TX
    assert _check_rawtxs(gamma.update(), payout=1)  # H2C PAYOUT TX
    assert _check_rawtxs(cron.run_all(), change=1)  # H2C CHANGE TX

    # close delta payment channel
    # recover | h2c | c2h |
    # --------+-----+-----+
    # commit  |  -  |  -  |
    # payout  |  -  |  -  |
    # change  |  X  |  X  |
    assert len(api.mph_status()["connections"]) == 1
    assert delta.close() is None
    assert len(api.mph_status()["connections"]) == 0
    assert _check_rawtxs(delta.update(), change=1)  # C2H CHANGE TX
    assert _check_rawtxs(cron.run_all(), change=1)  # H2C CHANGE TX

    _assert_states_synced(alpha.handle, alpha.c2h_state, alpha.h2c_state)
    _assert_states_synced(beta.handle, beta.c2h_state, beta.h2c_state)
    _assert_states_synced(gamma.handle, gamma.c2h_state, gamma.h2c_state)
    _assert_states_synced(delta.handle, delta.c2h_state, delta.h2c_state)
Beispiel #12
0
def test_user_doesnt_publish_commit(server_db):

    # fund server
    for i in range(2):
        address = lib.get_funding_addresses([ASSET])[ASSET]
        unsigned_rawtx = api.create_send(
            **{
                'source': FUNDING_ADDRESS,
                'destination': address,
                'asset': ASSET,
                'quantity': 1000000,
                'regular_dust_size': 1000000
            })
        signed_rawtx = scripts.sign_deposit(get_tx, FUNDING_WIF,
                                            unsigned_rawtx)
        api.sendrawtransaction(tx_hex=signed_rawtx)

    # connect clients
    assert len(api.mph_status()["connections"]) == 0
    clients = []
    for i in range(2):
        auth_wif = util.gen_funded_wif(ASSET, 1000000, 1000000)
        client = Mph(util.MockAPI(auth_wif=auth_wif))
        txid = client.connect(1000000, 42, asset=ASSET)
        assert txid is not None

        status = client.get_status()
        assert status["send_balance"] == 1000000
        assert status["send_deposit_ttl"] is not None
        assert status["recv_deposit_ttl"] is None  # hub deposit not yet made
        clients.append(client)
    assert len(api.mph_status()["connections"]) == 2

    # server funds deposits
    assert len(cron.fund_deposits()) == 2
    assert len(cron.fund_deposits()) == 0
    for client in clients:
        status = client.get_status()
        assert status["recv_deposit_ttl"] is not None  # hub deposit now made

    # before status
    alpha, beta = clients

    # send funds to beta
    alpha.micro_send(beta.handle, 42)
    alpha.sync()
    alpha_status = alpha.get_status()
    assert alpha_status["send_balance"] == 1000000 - 42 - 1

    # beta received funds
    beta.sync()
    beta_status = beta.get_status()
    assert beta_status["send_balance"] == 1000000 + 42 - 1

    # return some funds to alpha
    beta.micro_send(alpha.handle, 13)
    beta.sync()
    beta_status = beta.get_status()
    assert beta_status["send_balance"] == 1000000 + 42 - 1 - 13 - 1

    # alpha received funds
    alpha.sync()
    alpha_status = alpha.get_status()
    assert alpha_status["send_balance"] == 1000000 - 42 - 1 + 13 - 1

    # beta settles
    assert len(api.mph_status()["connections"]) == 2
    assert beta.close() is not None  # H2C COMMIT TX
    assert len(api.mph_status()["connections"]) == 1
    assert _check_rawtxs(beta.update())  # h2c payout delay not yet passed
    util_test.create_next_block(server_db)  # let payout delay pass
    assert _check_rawtxs(beta.update(), payout=1)  # H2C PAYOUT TX
    # H2C CHANGE TX, C2H COMMIT TX
    assert _check_rawtxs(cron.run_all(), change=1, commit=1)
    util_test.create_next_block(server_db)  # let c2h payout delay pass
    assert _check_rawtxs(cron.run_all(), payout=1)  # C2H PAYOUT TX
    assert _check_rawtxs(beta.update(), change=1)  # C2H CHANGE TX

    # let channel expire
    for i in range(50):
        util_test.create_next_block(server_db)

    # hub closes alice channel
    #        | h2c | c2h |
    # -------+-----+-----+
    # commit |  -  |  X  |
    # payout |  -  |  X  |
    # change |  -  |  -  |
    # expire |  X  |  -  |
    # C2H COMMIT TX, H2C EXPIRE TX
    assert _check_rawtxs(cron.run_all(), commit=1, expire=1)
    assert _check_rawtxs(cron.run_all(), payout=1)  # C2H PAYOUT TX
def test_standard_usage(server_db):

    # fund server
    for i in range(4):
        address = lib.get_funding_address()
        unsigned_rawtx = api.create_send(
            **{
                'source': FUNDING_ADDRESS,
                'destination': address,
                'asset': ASSET,
                'quantity': 1000000,
                'regular_dust_size': 1000000
            })
        signed_rawtx = scripts.sign_deposit(get_txs, FUNDING_WIF,
                                            unsigned_rawtx)
        api.sendrawtransaction(tx_hex=signed_rawtx)

    # connect clients
    assert len(api.mph_status()["connections"]) == 0
    clients = []
    for i in range(4):
        auth_wif = util.gen_funded_wif(ASSET, 1000000, 1000000)
        client = Mph(util.MockAPI(auth_wif=auth_wif))
        txid = client.connect(1000000, 42, asset=ASSET)
        assert txid is not None

        status = client.get_status()
        assert status["send_balance"] == 1000000
        assert status["send_deposit_ttl"] is not None
        assert status["recv_deposit_ttl"] is None  # hub deposit not yet made
        clients.append(client)
    assert len(api.mph_status()["connections"]) == 4

    # server funds deposits
    assert len(cron.fund_deposits()) == 4
    assert len(cron.fund_deposits()) == 0
    for client in clients:
        status = client.get_status()
        assert status["recv_deposit_ttl"] is not None  # hub deposit now made

    # before status
    alpha, beta, gamma, delta = clients
    alpha_before_status = alpha.get_status()
    beta_before_status = beta.get_status()
    gamma_before_status = gamma.get_status()

    # can send multiple payments
    alpha.micro_send(beta.handle, 5, "0000")
    alpha.micro_send(gamma.handle, 6, "0001")
    assert alpha.sync() == []
    assert beta.sync() == [{
        "payer_handle": alpha.handle,
        "amount": 5,
        "token": "0000"
    }]
    assert gamma.sync(), [{
        "payer_handle": alpha.handle,
        "amount": 6,
        "token": "0001"
    }]

    # send more back, commits are revoked to maximize liquidity
    beta.micro_send(alpha.handle, 42, "0003")
    assert beta.sync() == []
    assert alpha.sync() == [{
        "payer_handle": beta.handle,
        "amount": 42,
        "token": "0003"
    }]

    # multiple syncs/commtis from single client
    alpha.micro_send(beta.handle, 1, "0004")
    assert alpha.sync() == []

    # get after status
    alpha_after_status = alpha.get_status()
    beta_after_status = beta.get_status()
    gamma_after_status = gamma.get_status()

    # compare statuses
    alpha_after_status[
        "send_balance"] == alpha_before_status["send_balance"] + 27
    beta_after_status[
        "send_balance"] == beta_before_status["send_balance"] - 40
    gamma_after_status[
        "send_balance"] == gamma_before_status["send_balance"] + 5

    # client | c2h active | h2c active
    # -------+------------+-----------
    # alpha  | 1 commit   | 1 commit
    # beta   | 1 commit   | 0 commit
    # gamma  | 0 commit   | 1 commit
    # delta  | 0 commit   | 0 commit
    assert len(alpha.c2h_state["commits_active"]) == 1
    assert len(alpha.h2c_state["commits_active"]) == 1
    assert len(beta.c2h_state["commits_active"]) == 1
    assert len(beta.h2c_state["commits_active"]) == 0
    assert len(gamma.c2h_state["commits_active"]) == 0
    assert len(gamma.h2c_state["commits_active"]) == 1
    assert len(delta.c2h_state["commits_active"]) == 0
    assert len(delta.h2c_state["commits_active"]) == 0