Пример #1
0
 def __init__(self,
              msgchan,
              wallet,
              db,
              cj_amount,
              orders,
              input_utxos,
              my_cj_addr,
              my_change_addr,
              total_txfee,
              finishcallback,
              choose_orders_recover,
              commitment_creator
              ):
     """
     if my_change is None then there wont be a change address
     thats used if you want to entirely coinjoin one utxo with no change left over
     orders is the orders you want to fill {'counterpartynick': order1, 'cp2': order2}
     each order object is a dict of properties {'oid': 0, 'maxsize': 2000000, 'minsize':
         5000, 'cjfee': 10000, 'txfee': 5000}
     """
     log.info(
         'starting cj to ' + str(my_cj_addr) + ' with change at ' + str(
                 my_change_addr))
     # parameters
     self.msgchan = msgchan
     self.wallet = wallet
     self.db = db
     self.cj_amount = cj_amount
     self.active_orders = dict(orders)
     self.input_utxos = input_utxos
     self.finishcallback = finishcallback
     self.total_txfee = total_txfee
     self.my_cj_addr = my_cj_addr
     self.my_change_addr = my_change_addr
     self.choose_orders_recover = choose_orders_recover
     self.commitment_creator = commitment_creator
     self.timeout_lock = threading.Condition()  # used to wait() and notify()
     # used to restrict access to certain variables across threads
     self.timeout_thread_lock = threading.Condition()
     self.end_timeout_thread = False
     self.maker_timeout_sec = jm_single().maker_timeout_sec
     CoinJoinTX.TimeoutThread(self).start()
     # state variables
     self.txid = None
     self.cjfee_total = 0
     self.maker_txfee_contributions = 0
     self.nonrespondants = list(self.active_orders.keys())
     self.all_responded = False
     self.latest_tx = None
     # None means they belong to me
     self.utxos = {None: self.input_utxos.keys()}
     self.outputs = []
     # create DH keypair on the fly for this Tx object
     self.kp = init_keypair()
     self.crypto_boxes = {}
     if not self.get_commitment(input_utxos, self.cj_amount):
         return
     self.msgchan.fill_orders(self.active_orders, self.cj_amount,
                              self.kp.hex_pk(), self.commitment)
Пример #2
0
 def __init__(self,
              msgchan,
              wallet,
              db,
              cj_amount,
              orders,
              input_utxos,
              my_cj_addr,
              my_change_addr,
              total_txfee,
              finishcallback,
              choose_orders_recover,
              auth_addr=None):
     """
     if my_change is None then there wont be a change address
     thats used if you want to entirely coinjoin one utxo with no change left over
     orders is the orders you want to fill {'counterpartynick': order1, 'cp2': order2}
     each order object is a dict of properties {'oid': 0, 'maxsize': 2000000, 'minsize':
         5000, 'cjfee': 10000, 'txfee': 5000}
     """
     log.debug('starting cj to ' + str(my_cj_addr) + ' with change at ' +
               str(my_change_addr))
     # parameters
     self.msgchan = msgchan
     self.wallet = wallet
     self.db = db
     self.cj_amount = cj_amount
     self.active_orders = dict(orders)
     self.input_utxos = input_utxos
     self.finishcallback = finishcallback
     self.total_txfee = total_txfee
     self.my_cj_addr = my_cj_addr
     self.my_change_addr = my_change_addr
     self.choose_orders_recover = choose_orders_recover
     self.auth_addr = auth_addr
     self.timeout_lock = threading.Condition(
     )  # used to wait() and notify()
     # used to restrict access to certain variables across threads
     self.timeout_thread_lock = threading.Condition()
     self.end_timeout_thread = False
     self.maker_timeout_sec = jm_single().maker_timeout_sec
     CoinJoinTX.TimeoutThread(self).start()
     # state variables
     self.txid = None
     self.cjfee_total = 0
     self.maker_txfee_contributions = 0
     self.nonrespondants = list(self.active_orders.keys())
     self.all_responded = False
     self.latest_tx = None
     # None means they belong to me
     self.utxos = {None: self.input_utxos.keys()}
     self.outputs = []
     # create DH keypair on the fly for this Tx object
     self.kp = init_keypair()
     self.crypto_boxes = {}
     self.msgchan.fill_orders(self.active_orders, self.cj_amount,
                              self.kp.hex_pk())
Пример #3
0
    def __init__(self, maker, nick, oid, amount, taker_pk):
        self.tx = None
        self.i_utxo_pubkey = None

        self.maker = maker
        self.oid = oid
        self.cj_amount = amount
        if self.cj_amount <= jm_single().DUST_THRESHOLD:
            self.maker.msgchan.send_error(nick, 'amount below dust threshold')
        # the btc pubkey of the utxo that the taker plans to use as input
        self.taker_pk = taker_pk
        # create DH keypair on the fly for this Order object
        self.kp = init_keypair()
        # the encryption channel crypto box for this Order object
        self.crypto_box = as_init_encryption(self.kp,
                                             init_pubkey(taker_pk))

        order_s = [o for o in maker.orderlist if o['oid'] == oid]
        if len(order_s) == 0:
            self.maker.msgchan.send_error(nick, 'oid not found')
        order = order_s[0]
        if amount < order['minsize'] or amount > order['maxsize']:
            self.maker.msgchan.send_error(nick, 'amount out of range')
        self.ordertype = order['ordertype']
        self.txfee = order['txfee']
        self.cjfee = order['cjfee']
        log.debug('new cjorder nick=%s oid=%d amount=%d' % (nick, oid, amount))
        self.utxos, self.cj_addr, self.change_addr = maker.oid_to_order(
                self, oid, amount)
        self.maker.wallet.update_cache_index()
        if not self.utxos:
            self.maker.msgchan.send_error(
                    nick, 'unable to fill order constrained by dust avoidance')
            # TODO make up orders offers in a way that this error cant appear
            #  check nothing has messed up with the wallet code, remove this
            # code after a while
        import pprint
        log.debug('maker utxos = ' + pprint.pformat(self.utxos))
        utxo_list = self.utxos.keys()
        utxo_data = jm_single().bc_interface.query_utxo_set(utxo_list)
        if None in utxo_data:
            log.debug('wrongly using an already spent utxo. utxo_data = ' +
                      pprint.pformat(utxo_data))
            sys.exit(0)
        for utxo, data in zip(utxo_list, utxo_data):
            if self.utxos[utxo]['value'] != data['value']:
                fmt = 'wrongly labeled utxo, expected value: {} got {}'.format
                log.debug(fmt(self.utxos[utxo]['value'], data['value']))
                sys.exit(0)

        # always a new address even if the order ends up never being
        # furfilled, you dont want someone pretending to fill all your
        # orders to find out which addresses you use
        self.maker.msgchan.send_pubkey(nick, self.kp.hex_pk())
Пример #4
0
    def __init__(self, maker, nick, oid, amount, taker_pk):
        self.tx = None
        self.i_utxo_pubkey = None

        self.maker = maker
        self.oid = oid
        self.cj_amount = amount
        if self.cj_amount <= jm_single().DUST_THRESHOLD:
            self.maker.msgchan.send_error(nick, 'amount below dust threshold')
        # the btc pubkey of the utxo that the taker plans to use as input
        self.taker_pk = taker_pk
        # create DH keypair on the fly for this Order object
        self.kp = init_keypair()
        # the encryption channel crypto box for this Order object
        self.crypto_box = as_init_encryption(self.kp,
                                             init_pubkey(taker_pk))

        order_s = [o for o in maker.orderlist if o['oid'] == oid]
        if len(order_s) == 0:
            self.maker.msgchan.send_error(nick, 'oid not found')
        order = order_s[0]
        if amount < order['minsize'] or amount > order['maxsize']:
            self.maker.msgchan.send_error(nick, 'amount out of range')
        self.ordertype = order['ordertype']
        self.txfee = order['txfee']
        self.cjfee = order['cjfee']
        log.debug('new cjorder nick=%s oid=%d amount=%d' % (nick, oid, amount))
        self.utxos, self.cj_addr, self.change_addr = maker.oid_to_order(
                self, oid, amount)
        self.maker.wallet.update_cache_index()
        if not self.utxos:
            self.maker.msgchan.send_error(
                    nick, 'unable to fill order constrained by dust avoidance')
            # TODO make up orders offers in a way that this error cant appear
            #  check nothing has messed up with the wallet code, remove this
            # code after a while
        import pprint
        log.debug('maker utxos = ' + pprint.pformat(self.utxos))
        utxo_list = self.utxos.keys()
        utxo_data = jm_single().bc_interface.query_utxo_set(utxo_list)
        if None in utxo_data:
            log.debug('wrongly using an already spent utxo. utxo_data = ' +
                      pprint.pformat(utxo_data))
            sys.exit(0)
        for utxo, data in zip(utxo_list, utxo_data):
            if self.utxos[utxo]['value'] != data['value']:
                fmt = 'wrongly labeled utxo, expected value: {} got {}'.format
                log.debug(fmt(self.utxos[utxo]['value'], data['value']))
                sys.exit(0)

        # always a new address even if the order ends up never being
        # furfilled, you dont want someone pretending to fill all your
        # orders to find out which addresses you use
        self.maker.msgchan.send_pubkey(nick, self.kp.hex_pk())
Пример #5
0
    def __init__(self, maker, nick, oid, amount, taker_pk):
        self.tx = None
        self.i_utxo_pubkey = None

        self.maker = maker
        self.oid = oid
        self.cj_amount = amount
        if self.cj_amount <= jm_single().BITCOIN_DUST_THRESHOLD:
            self.maker.msgchan.send_error(nick, 'amount below dust threshold')
        # the btc pubkey of the utxo that the taker plans to use as input
        self.taker_pk = taker_pk
        # create DH keypair on the fly for this Order object
        self.kp = init_keypair()
        # the encryption channel crypto box for this Order object.
        # Invalid pubkeys must be handled by giving up gracefully (otherwise DOS)
        try:
            self.crypto_box = as_init_encryption(self.kp,
                                             init_pubkey(taker_pk))
        except NaclError as e:
            log.info("Unable to setup crypto box with counterparty: " + repr(e))
            self.maker.msgchan.send_error(nick, "invalid nacl pubkey: " + taker_pk)
            return

        order_s = [o for o in maker.orderlist if o['oid'] == oid]
        if len(order_s) == 0:
            self.maker.msgchan.send_error(nick, 'oid not found')
        order = order_s[0]
        if amount < order['minsize'] or amount > order['maxsize']:
            self.maker.msgchan.send_error(nick, 'amount out of range')
        self.ordertype = order['ordertype']
        self.txfee = order['txfee']
        self.cjfee = order['cjfee']
        log.info('new cjorder nick=%s oid=%d amount=%d' % (nick, oid, amount))

        def populate_utxo_data():
            self.utxos, self.cj_addr, self.change_addr = maker.oid_to_order(
                self, oid, amount)
            self.maker.wallet.update_cache_index()
            if not self.utxos:
                self.maker.msgchan.send_error(
                    nick, 'unable to fill order constrained by dust avoidance')
            # TODO make up orders offers in a way that this error cant appear
            #  check nothing has messed up with the wallet code, remove this
            # code after a while
            log.debug('maker utxos = ' + pprint.pformat(self.utxos))
            utxos = self.utxos.keys()
            return (utxos, jm_single().bc_interface.query_utxo_set(utxos))

        for i in xrange(10): ##only loop 10 times, not an infinite amount
            utxo_list, utxo_data = populate_utxo_data()
            if None not in utxo_data:
                break
            log.debug('wrongly selected stale utxos! utxo_data = ' +
                      pprint.pformat(utxo_data))
            with self.maker.wallet_unspent_lock:
                jm_single().bc_interface.sync_unspent(self.maker.wallet)
        if None in utxo_data:
            log.error('unable to select non-stale utxo, weird error! quitting')
            sys.exit(0)

        for utxo, data in zip(utxo_list, utxo_data):
            if self.utxos[utxo]['value'] != data['value']:
                fmt = 'wrongly labeled utxo, expected value: {} got {}'.format
                log.debug(fmt(self.utxos[utxo]['value'], data['value']))
                sys.exit(0)

        # always a new address even if the order ends up never being
        # furfilled, you dont want someone pretending to fill all your
        # orders to find out which addresses you use
        self.maker.msgchan.send_pubkey(nick, self.kp.hex_pk())
Пример #6
0
    def __init__(self, maker, nick, oid, amount, taker_pk):
        self.tx = None
        self.i_utxo_pubkey = None

        self.maker = maker
        self.oid = oid
        self.cj_amount = amount
        if self.cj_amount <= jm_single().BITCOIN_DUST_THRESHOLD:
            self.maker.msgchan.send_error(nick, 'amount below dust threshold')
        # the btc pubkey of the utxo that the taker plans to use as input
        self.taker_pk = taker_pk
        # create DH keypair on the fly for this Order object
        self.kp = init_keypair()
        # the encryption channel crypto box for this Order object.
        # Invalid pubkeys must be handled by giving up gracefully (otherwise DOS)
        try:
            self.crypto_box = as_init_encryption(self.kp,
                                                 init_pubkey(taker_pk))
        except NaclError as e:
            log.info("Unable to setup crypto box with counterparty: " +
                     repr(e))
            self.maker.msgchan.send_error(nick,
                                          "invalid nacl pubkey: " + taker_pk)
            return

        order_s = [o for o in maker.orderlist if o['oid'] == oid]
        if len(order_s) == 0:
            self.maker.msgchan.send_error(nick, 'oid not found')
        order = order_s[0]
        if amount < order['minsize'] or amount > order['maxsize']:
            self.maker.msgchan.send_error(nick, 'amount out of range')
        self.ordertype = order['ordertype']
        self.txfee = order['txfee']
        self.cjfee = order['cjfee']
        log.info('new cjorder nick=%s oid=%d amount=%d' % (nick, oid, amount))

        def populate_utxo_data():
            self.utxos, self.cj_addr, self.change_addr = maker.oid_to_order(
                self, oid, amount)
            self.maker.wallet.update_cache_index()
            if not self.utxos:
                self.maker.msgchan.send_error(
                    nick, 'unable to fill order constrained by dust avoidance')
            # TODO make up orders offers in a way that this error cant appear
            #  check nothing has messed up with the wallet code, remove this
            # code after a while
            log.debug('maker utxos = ' + pprint.pformat(self.utxos))
            utxos = self.utxos.keys()
            return (utxos, jm_single().bc_interface.query_utxo_set(utxos))

        for i in xrange(10):  ##only loop 10 times, not an infinite amount
            utxo_list, utxo_data = populate_utxo_data()
            if None not in utxo_data:
                break
            log.debug('wrongly selected stale utxos! utxo_data = ' +
                      pprint.pformat(utxo_data))
            with self.maker.wallet_unspent_lock:
                jm_single().bc_interface.sync_unspent(self.maker.wallet)
        if None in utxo_data:
            log.error('unable to select non-stale utxo, weird error! quitting')
            sys.exit(0)

        for utxo, data in zip(utxo_list, utxo_data):
            if self.utxos[utxo]['value'] != data['value']:
                fmt = 'wrongly labeled utxo, expected value: {} got {}'.format
                log.debug(fmt(self.utxos[utxo]['value'], data['value']))
                sys.exit(0)

        # always a new address even if the order ends up never being
        # furfilled, you dont want someone pretending to fill all your
        # orders to find out which addresses you use
        self.maker.msgchan.send_pubkey(nick, self.kp.hex_pk())