def test_no_keys_with_sufficient_btc(): # create asset unsigned_rawtx = api.create_issuance( source=FUNDING_ADDRESS, asset="A7736697071037023001", quantity=100000000 ) signed_rawtx = scripts.sign_deposit(get_tx, FUNDING_WIF, unsigned_rawtx) api.sendrawtransaction(tx_hex=signed_rawtx) # fund server for i in range(3): addresses = lib.get_funding_addresses(["XCP", "A7736697071037023001"]) for asset, address in addresses.items(): 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) key = lib.find_key_with_funds("XCP", 1000000, 1000001) assert key is None
def test_no_keys_with_sufficient_btc(): # create asset unsigned_rawtx = api.create_issuance(source=FUNDING_ADDRESS, asset="A7736697071037023001", quantity=100000000) signed_rawtx = scripts.sign_deposit(get_tx, FUNDING_WIF, unsigned_rawtx) api.sendrawtransaction(tx_hex=signed_rawtx) # fund server for i in range(3): addresses = lib.get_funding_addresses(["XCP", "A7736697071037023001"]) for asset, address in addresses.items(): 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) key = lib.find_key_with_funds("XCP", 1000000, 1000001) assert key is None
def test_get_hub_liquidity(server_db): # confirmed fund hub_wif = lib.load_wif() hub_address = keys.address_from_wif(hub_wif) unsigned_rawtx = api.create_send(**{ 'source': FUNDING_ADDRESS, 'destination': hub_address, 'asset': ASSET, 'quantity': 2000000, 'regular_dust_size': 2000000 }) signed_rawtx = scripts.sign_deposit(get_txs, FUNDING_WIF, unsigned_rawtx) api.sendrawtransaction(tx_hex=signed_rawtx) assert lib.get_hub_liquidity() == { 'A7736697071037023001': 0, 'BTC': 2000000, 'XCP': 2000000 } # unconfirmed send wif = keys.generate_wif("XTN") address = keys.address_from_wif(wif) unsigned_rawtx = api.create_send(**{ 'source': hub_address, 'destination': address, 'asset': ASSET, 'quantity': 1000000, 'fee': 1000000 }) signed_rawtx = scripts.sign_deposit(get_txs, hub_wif, unsigned_rawtx) util_test.insert_unconfirmed_raw_transaction(signed_rawtx, server_db) # counts unconfurmed sends assert lib.get_hub_liquidity() == { 'A7736697071037023001': 0, 'BTC': 0, # no utxos left 'XCP': 1000000 } # unconfurmed fund unsigned_rawtx = api.create_send(**{ 'source': FUNDING_ADDRESS, 'destination': hub_address, 'asset': ASSET, 'quantity': 2000000, 'regular_dust_size': 2000000 }) signed_rawtx = scripts.sign_deposit(get_txs, FUNDING_WIF, unsigned_rawtx) util_test.insert_unconfirmed_raw_transaction(signed_rawtx, server_db) # doesnt counts unconfurmed funds assert lib.get_hub_liquidity() == { 'A7736697071037023001': 0, 'BTC': 0, # no utxos left 'XCP': 1000000 } utxos = api.get_unspent_txouts(address=hub_address, unconfirmed=False) assert utxos == []
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
def send_funds(destination, asset, quantity): from picopayments_hub import api try: regular_dust_size = 5500 # TODO get from cplib fee_per_kb = 25000 # TODO get from cplib fee = int(fee_per_kb / 2) extra_btc = (fee + regular_dust_size) * 3 wif = load_wif() address = keys.address_from_wif(wif) utxos = _get_hub_utxos(address, asset, quantity, extra_btc) unsigned_rawtx = api.create_send( source=address, destination=destination, asset=asset, regular_dust_size=extra_btc, quantity=quantity, disable_utxo_locks=True, custom_inputs=utxos, ) signed_rawtx = scripts.sign_deposit(get_txs, wif, unsigned_rawtx) txid = publish(signed_rawtx) assert txid, "Failed to publish transaction: {0}".format(signed_rawtx) return {"txid": txid, "rawtx": signed_rawtx} except err.InsufficientFunds: print("Insufficient funds!") return None
def send_funds(destination, asset, quantity): from picopayments import api extra_btc = _get_fee_multaple(factor=3) key = find_key_with_funds(asset, quantity, extra_btc) if key is None: raise err.InsufficientFunds(asset, quantity) unsigned_rawtx = api.locked_create_send(source=key["address"], destination=destination, asset=asset, regular_dust_size=extra_btc, quantity=quantity) _LOCKS[key["address"]] = cachetools.TTLCache(_LOCKS_MAX, _LOCKS_TTL) signed_rawtx = scripts.sign_deposit(get_tx, key["wif"], unsigned_rawtx) return publish(signed_rawtx)
def gen_funded_wif(asset, asset_quantity, btc_quantity): src_wif = DP["addresses"][0][2] src_address = address_from_wif(src_wif) dest_wif = generate_wif(netcode=etc.netcode) dest_address = address_from_wif(dest_wif) unsigned_rawtx = api.create_send(**{ 'source': src_address, 'destination': dest_address, 'asset': asset, 'quantity': asset_quantity, 'regular_dust_size': btc_quantity }) signed_rawtx = scripts.sign_deposit(get_txs, src_wif, unsigned_rawtx) api.sendrawtransaction(tx_hex=signed_rawtx) return dest_wif
def gen_funded_wif(asset, asset_quantity, btc_quantity): src_wif = DP["addresses"][0][2] src_address = address_from_wif(src_wif) dest_wif = generate_wif(netcode=etc.netcode) dest_address = address_from_wif(dest_wif) unsigned_rawtx = api.create_send( **{ 'source': src_address, 'destination': dest_address, 'asset': asset, 'quantity': asset_quantity, 'regular_dust_size': btc_quantity }) signed_rawtx = scripts.sign_deposit(get_tx, src_wif, unsigned_rawtx) api.sendrawtransaction(tx_hex=signed_rawtx) return dest_wif
def send_funds(destination, asset, quantity): from picopayments_hub import api regular_dust_size = 5500 # FIXME get from cplib fee_per_kb = 25000 # FIXME get from cplib fee = int(fee_per_kb / 2) extra_btc = (fee + regular_dust_size) * 3 key = find_key_with_funds(asset, quantity, extra_btc) if key is None: raise err.InsufficientFunds(asset, quantity) unsigned_rawtx = api.create_send( source=key["address"], destination=destination, asset=asset, regular_dust_size=extra_btc, quantity=quantity, ) _LOCKS[key["address"]] = cachetools.TTLCache(_LOCKS_MAX, _LOCKS_TTL) signed_rawtx = scripts.sign_deposit(get_tx, key["wif"], unsigned_rawtx) return publish(signed_rawtx)
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_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_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
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_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 sign(self, unsigned_rawtx, wif): """TODO doc string""" return scripts.sign_deposit(self.get_rawtx, wif, unsigned_rawtx)
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)
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
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