Example #1
0
    def close(self):

        # publish h2c commit if possible
        commit_rawtx = self.finalize_commit(self._get_wif, self.h2c_state)
        if commit_rawtx is not None:
            self._history_add_published_h2c_commit(commit_rawtx)

        # get h2c spend secret if no commits for channel
        h2c_spend_secret = None
        if len(self.h2c_state["commits_active"]) == 0:
            deposit_script = self.h2c_state["deposit_script"]
            spend_hash = scripts.get_deposit_spend_secret_hash(deposit_script)
            h2c_spend_secret = self.secrets[spend_hash]

        # tell hub to close the channel
        result = self.api.mph_close(handle=self.handle,
                                    spend_secret=h2c_spend_secret)

        # remember c2h spend secret if given
        c2h_spend_secret = result["spend_secret"]
        if c2h_spend_secret:
            secret_hash = util.hash160hex(c2h_spend_secret)
            self.secrets[secret_hash] = c2h_spend_secret

        return commit_rawtx
Example #2
0
def publish_commits():
    with etc.database_lock:
        txids = []
        cursor = sql.get_cursor()
        for hub_connection in db.hub_connections_complete(cursor=cursor):
            asset = hub_connection["asset"]
            c2h_mpc_id = hub_connection["c2h_channel_id"]
            c2h_state = db.load_channel_state(c2h_mpc_id, asset, cursor=cursor)
            h2c_mpc_id = hub_connection["h2c_channel_id"]
            h2c_state = db.load_channel_state(h2c_mpc_id, asset, cursor=cursor)
            h2c_spend_secret_hash = get_deposit_spend_secret_hash(
                h2c_state["deposit_script"])
            h2c_spend_secret = lib.get_secret(h2c_spend_secret_hash)
            c2h_expired = lib.is_expired(c2h_state, etc.expire_clearance)
            h2c_expired = lib.is_expired(h2c_state, etc.expire_clearance)
            expired = c2h_expired or h2c_expired
            h2c_commits_published = api.mpc_published_commits(state=h2c_state)
            closed = hub_connection["closed"] != 0

            # connection expired or commit published or spend secret known
            if expired or closed or h2c_commits_published or h2c_spend_secret:
                if not closed:
                    db.set_connection_closed(handle=hub_connection["handle"])
                c2h_commits_published = api.mpc_published_commits(
                    state=c2h_state)
                if len(c2h_commits_published) == 0:
                    txid = Mpc(api).finalize_commit(lib.get_wif, c2h_state)
                    if txid:
                        txids.append(txid)

        return txids
Example #3
0
def publish_commits():
    with etc.database_lock:
        commit_rawtxs = []
        cursor = sql.get_cursor()
        for hub_connection in db.hub_connections_complete(cursor=cursor):
            asset = hub_connection["asset"]
            c2h_mpc_id = hub_connection["c2h_channel_id"]
            c2h_state = db.load_channel_state(c2h_mpc_id, asset, cursor=cursor)
            h2c_mpc_id = hub_connection["h2c_channel_id"]
            h2c_state = db.load_channel_state(h2c_mpc_id, asset, cursor=cursor)
            h2c_spend_secret_hash = get_deposit_spend_secret_hash(
                h2c_state["deposit_script"]
            )
            h2c_spend_secret = lib.get_secret(h2c_spend_secret_hash)
            c2h_expired = lib.is_expired(c2h_state, etc.expire_clearance)
            h2c_expired = lib.is_expired(h2c_state, etc.expire_clearance)
            expired = c2h_expired or h2c_expired
            h2c_commits_published = api.mpc_published_commits(state=h2c_state)
            closed = hub_connection["closed"] != 0

            # connection expired or commit published or spend secret known
            if expired or closed or h2c_commits_published or h2c_spend_secret:
                if not closed:
                    db.set_connection_closed(handle=hub_connection["handle"])
                rawtx = Mpc(api).finalize_commit(lib.get_wif, c2h_state)
                if rawtx:
                    commit_rawtxs.append(rawtx)

        return commit_rawtxs
Example #4
0
def close_connection(handle, h2c_spend_secret=None):

    cursor = sql.get_cursor()
    hub_connection = db.hub_connection(handle=handle, cursor=cursor)

    # save secret if given and not already known
    if h2c_spend_secret is not None:
        secret_hash = util.hash160hex(h2c_spend_secret)
        if not get_secret(secret_hash):
            db.add_secret(secret_value=h2c_spend_secret,
                          secret_hash=secret_hash,
                          cursor=cursor)

    # close connection if not already done
    if not hub_connection["closed"]:
        db.set_connection_closed(handle=handle, cursor=cursor)

    # get c2h spend secret if no commits for channel
    c2h_spend_secret = None
    c2h_state = db.load_channel_state(hub_connection["c2h_channel_id"],
                                      hub_connection["asset"],
                                      cursor=cursor)
    if len(c2h_state["commits_active"]) == 0:
        c2h_spend_secret_hash = scripts.get_deposit_spend_secret_hash(
            c2h_state["deposit_script"])
        c2h_spend_secret = get_secret(c2h_spend_secret_hash)

    hub_key = db.channel_payer_key(id=hub_connection["h2c_channel_id"])
    return ({"spend_secret": c2h_spend_secret}, hub_key["wif"])
Example #5
0
def close_connection(handle, h2c_spend_secret=None):

    cursor = sql.get_cursor()
    hub_connection = db.hub_connection(handle=handle, cursor=cursor)

    # save secret if given and not already known
    if h2c_spend_secret is not None:
        secret_hash = util.hash160hex(h2c_spend_secret)
        if not get_secret(secret_hash):
            db.add_secret(secret_value=h2c_spend_secret,
                          secret_hash=secret_hash, cursor=cursor)

    # close connection if not already done
    if not hub_connection["closed"]:
        db.set_connection_closed(handle=handle, cursor=cursor)

    # get c2h spend secret if no commits for channel
    c2h_spend_secret = None
    c2h_state = db.load_channel_state(hub_connection["c2h_channel_id"],
                                      hub_connection["asset"], cursor=cursor)
    if len(c2h_state["commits_active"]) == 0:
        c2h_spend_secret_hash = scripts.get_deposit_spend_secret_hash(
            c2h_state["deposit_script"]
        )
        c2h_spend_secret = get_secret(c2h_spend_secret_hash)

    hub_wif = load_wif()
    return ({"spend_secret": c2h_spend_secret}, hub_wif)
Example #6
0
    def full_duplex_recover_funds(self, get_wif_func, get_secret_func,
                                  recv_state, send_state):

        # get send spend secret if known
        send_spend_secret_hash = scripts.get_deposit_spend_secret_hash(
            send_state["deposit_script"]
        )
        send_spend_secret = get_secret_func(send_spend_secret_hash)

        txids = []

        # get payouts
        for payout_tx in self.api.mpc_payouts(state=recv_state):
            txids.append(self.recover_payout(
                get_wif_func=get_wif_func,
                get_secret_func=get_secret_func,
                **payout_tx
            ))

        rtxs = self.api.mpc_recoverables(state=send_state,
                                         spend_secret=send_spend_secret)
        for revoke_tx in rtxs["revoke"]:
            txids.append(self.recover_revoked(
                get_wif_func=get_wif_func, **revoke_tx
            ))
        for change_tx in rtxs["change"]:
            txids.append(self.recover_change(
                get_wif_func=get_wif_func, **change_tx
            ))
        for expire_tx in rtxs["expire"]:
            txids.append(self.recover_expired(
                get_wif_func=get_wif_func, **expire_tx
            ))
        return txids
Example #7
0
def close_input(handle, client_pubkey, spend_secret):
    hub_connection(handle)
    _channel_client(handle, client_pubkey)

    # validate spend secret for h2c deposit
    if spend_secret is not None:
        validate.is_string(spend_secret)
        spend_secret_hash = util.hash160hex(spend_secret)
        deposit_script = db.h2c_channel(handle=handle)["deposit_script"]
        expected_hash = scripts.get_deposit_spend_secret_hash(deposit_script)
        if expected_hash != spend_secret_hash:
            raise err.InvalidSpendSecret(expected_hash, spend_secret)
Example #8
0
def close_input(handle, client_pubkey, spend_secret):
    hub_connection(handle)
    _channel_client(handle, client_pubkey)

    # validate spend secret for h2c deposit
    if spend_secret is not None:
        validate.is_string(spend_secret)
        spend_secret_hash = util.hash160hex(spend_secret)
        deposit_script = db.h2c_channel(handle=handle)["deposit_script"]
        expected_hash = scripts.get_deposit_spend_secret_hash(deposit_script)
        if expected_hash != spend_secret_hash:
            raise err.InvalidSpendSecret(expected_hash, spend_secret)
Example #9
0
    def full_duplex_recover_funds(self, get_wif_func, get_secret_func,
                                  recv_state, send_state):

        # get send spend secret if known
        send_spend_secret_hash = scripts.get_deposit_spend_secret_hash(
            send_state["deposit_script"])
        send_spend_secret = get_secret_func(send_spend_secret_hash)

        rawtxs = {
            "payout": {},  # {"txid": "rawtx"}
            "revoke": {},  # {"txid": "rawtx"}
            "change": {},  # {"txid": "rawtx"}
            "expire": {},  # {"txid": "rawtx"}
            "commit": {},  # {"txid": "rawtx"}
            "deposit": {},  # {"txid": "rawtx"}
        }

        # get payouts
        for payout_tx in self.api.mpc_payouts(state=recv_state):
            rawtx = self.recover_payout(get_wif_func=get_wif_func,
                                        get_secret_func=get_secret_func,
                                        **payout_tx)
            rawtxs["payout"][util.gettxid(rawtx)] = rawtx

        rtxs = self.api.mpc_recoverables(state=send_state,
                                         spend_secret=send_spend_secret)
        for revoke_tx in rtxs["revoke"]:
            rawtx = self.recover_revoked(get_wif_func=get_wif_func,
                                         **revoke_tx)
            rawtxs["revoke"][util.gettxid(rawtx)] = rawtx

        for change_tx in rtxs["change"]:
            rawtx = self.recover_change(get_wif_func=get_wif_func, **change_tx)
            rawtxs["change"][util.gettxid(rawtx)] = rawtx

        for expire_tx in rtxs["expire"]:
            rawtx = self.recover_expired(get_wif_func=get_wif_func,
                                         **expire_tx)
            rawtxs["expire"][util.gettxid(rawtx)] = rawtx

        return rawtxs
Example #10
0
    def close(self):
        commit_txid = self.finalize_commit(self._get_wif, self.h2c_state)

        # get h2c spend secret if no commits for channel
        h2c_spend_secret = None
        if len(self.h2c_state["commits_active"]) == 0:
            deposit_script = self.h2c_state["deposit_script"]
            spend_hash = scripts.get_deposit_spend_secret_hash(deposit_script)
            h2c_spend_secret = self.secrets[spend_hash]

        # tell hub to close the channel
        result = self.api.mph_close(handle=self.handle,
                                    spend_secret=h2c_spend_secret)

        # remember c2h spend secret if given
        c2h_spend_secret = result["spend_secret"]
        if c2h_spend_secret:
            secret_hash = util.hash160hex(c2h_spend_secret)
            self.secrets[secret_hash] = c2h_spend_secret

        return commit_txid
    def full_duplex_channel_status(self,
                                   handle,
                                   netcode,
                                   send_state,
                                   recv_state,
                                   get_secret_func,
                                   clearance=6):
        assert (send_state["asset"] == recv_state["asset"])
        asset = send_state["asset"]

        send_ttl = self.api.mpc_deposit_ttl(state=send_state,
                                            clearance=clearance)
        send_script = send_state["deposit_script"]
        send_deposit_expire_time = scripts.get_deposit_expire_time(send_script)
        send_deposit_address = util.script_address(send_script,
                                                   netcode=netcode)
        send_balances = self.get_balances(send_deposit_address, ["BTC", asset])
        send_deposit = send_balances.get(asset, 0)
        send_transferred = 0
        if len(send_state["commits_active"]) > 0:
            send_transferred = self.api.mpc_transferred_amount(
                state=send_state)

        recv_ttl = self.api.mpc_deposit_ttl(state=recv_state,
                                            clearance=clearance)
        recv_script = recv_state["deposit_script"]
        recv_deposit_expire_time = scripts.get_deposit_expire_time(recv_script)
        recv_deposit_address = util.script_address(recv_script,
                                                   netcode=netcode)
        recv_balances = self.get_balances(recv_deposit_address, ["BTC", asset])
        recv_deposit = recv_balances.get(asset, 0)
        recv_transferred = 0
        if len(recv_state["commits_active"]) > 0:
            recv_transferred = self.api.mpc_transferred_amount(
                state=recv_state)

        send_balance = send_deposit + recv_transferred - send_transferred
        recv_balance = recv_deposit + send_transferred - recv_transferred

        ttl = None
        if send_ttl is not None and recv_ttl is not None:
            ttl = min(send_ttl, recv_ttl)

        # get connection status
        status = "opening"
        if send_ttl and recv_ttl:
            status = "open"
        send_secret_hash = scripts.get_deposit_spend_secret_hash(send_script)
        send_secret = get_secret_func(send_secret_hash)
        send_commits_published = self.api.mpc_published_commits(
            state=send_state)
        expired = ttl == 0  # None explicitly ignore as channel opening
        if expired or send_secret or send_commits_published:
            status = "closed"
            send_balance = send_deposit
            recv_balance = 0

        return {
            # FIXME get channel tx history
            "status": status,
            "asset": asset,
            "netcode": netcode,
            "balance": send_balance,
            "ttl": ttl,
            "send_balance": send_balance,
            "send_deposit_address": send_deposit_address,
            "send_deposit_ttl": send_ttl,
            "send_deposit_balances": send_balances,
            "send_deposit_expire_time": send_deposit_expire_time,
            "send_commits_published": send_commits_published,
            "send_transferred_quantity": send_transferred,
            "recv_balance": recv_balance,
            "recv_deposit_address": recv_deposit_address,
            "recv_deposit_ttl": recv_ttl,
            "recv_deposit_balances": recv_balances,
            "recv_deposit_expire_time": recv_deposit_expire_time,
            "recv_transferred_quantity": recv_transferred,
        }