Пример #1
0
    def oid_to_order(self, offer, amount):
        total_amount = amount + offer["txfee"]
        real_cjfee = calc_cj_fee(offer["ordertype"], offer["cjfee"], amount)
        required_amount = total_amount + \
            jm_single().DUST_THRESHOLD + 1 - real_cjfee

        mix_balance = self.get_available_mixdepths()
        filtered_mix_balance = {
            m: b
            for m, b in mix_balance.items() if b >= required_amount
        }
        if not filtered_mix_balance:
            return None, None, None
        jlog.debug('mix depths that have enough = ' +
                   str(filtered_mix_balance))
        mixdepth = self.select_input_mixdepth(filtered_mix_balance, offer,
                                              amount)
        if mixdepth is None:
            return None, None, None
        jlog.info('filling offer, mixdepth=' + str(mixdepth) + ', amount=' +
                  str(amount))

        cj_addr = self.select_output_address(mixdepth, offer, amount)
        if cj_addr is None:
            return None, None, None
        jlog.info('sending output to address=' + str(cj_addr))

        change_addr = self.wallet_service.get_internal_addr(mixdepth)

        utxos = self.wallet_service.select_utxos(mixdepth,
                                                 required_amount,
                                                 minconfs=1,
                                                 includeaddr=True)

        return utxos, cj_addr, change_addr
Пример #2
0
 def on_tx_confirmed(self, offer, confirmations, txid):
     if offer["cjaddr"] in self.tx_unconfirm_timestamp:
         confirm_time = int(time.time()) - self.tx_unconfirm_timestamp[
             offer["cjaddr"]]
     else:
         confirm_time = 0
     timestamp = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
     real_cjfee = calc_cj_fee(offer["offer"]["ordertype"],
                              offer["offer"]["cjfee"], offer["amount"])
     self.log_statement([timestamp, offer["amount"], len(
         offer["utxos"]), sum([av['value'] for av in offer["utxos"].values(
         )]), real_cjfee, real_cjfee - offer["offer"]["txfee"], round(
             confirm_time / 60.0, 2), ''])
     return self.on_tx_unconfirmed(offer, txid, None)
    def oid_to_order(self, offer, amount):
        total_amount = amount + offer["txfee"]
        mix_balance = self.get_available_mixdepths()

        filtered_mix_balance = {
            m: b
            for m, b in mix_balance.items() if b >= total_amount
        }
        if not filtered_mix_balance:
            return None, None, None
        jlog.debug('mix depths that have enough = ' +
                   str(filtered_mix_balance))
        mixdepth = self.select_input_mixdepth(filtered_mix_balance, offer,
                                              amount)
        if mixdepth is None:
            return None, None, None
        jlog.info('filling offer, mixdepth=' + str(mixdepth) + ', amount=' +
                  str(amount))

        cj_addr = self.select_output_address(mixdepth, offer, amount)
        if cj_addr is None:
            return None, None, None
        jlog.info('sending output to address=' + str(cj_addr))

        change_addr = self.wallet_service.get_internal_addr(mixdepth)

        utxos = self.wallet_service.select_utxos(mixdepth,
                                                 total_amount,
                                                 minconfs=1,
                                                 includeaddr=True)
        my_total_in = sum([va['value'] for va in utxos.values()])
        real_cjfee = calc_cj_fee(offer["ordertype"], offer["cjfee"], amount)
        change_value = my_total_in - amount - offer["txfee"] + real_cjfee
        if change_value <= jm_single().DUST_THRESHOLD:
            jlog.debug(('change value={} below dust threshold, '
                        'finding new utxos').format(change_value))
            try:
                utxos = self.wallet_service.select_utxos(
                    mixdepth,
                    total_amount + jm_single().DUST_THRESHOLD,
                    minconfs=1,
                    includeaddr=True)
            except Exception:
                jlog.info('dont have the required UTXOs to make a '
                          'output above the dust threshold, quitting')
                return None, None, None

        return utxos, cj_addr, change_addr
Пример #4
0
    def create_depth_chart(self, cj_amount, args=None):
        if 'matplotlib' not in sys.modules:
            return 'matplotlib not installed, charts not available'

        if args is None:
            args = {}
        try:
            self.taker.dblock.acquire(True)
            rows = self.taker.db.execute('SELECT * FROM orderbook;').fetchall()
        finally:
            self.taker.dblock.release()
        sqlorders = [
            o for o in rows if o["ordertype"] in filtered_offername_list
        ]
        orderfees = sorted([
            calc_cj_fee(o['ordertype'], o['cjfee'], cj_amount) / 1e8
            for o in sqlorders if o['minsize'] <= cj_amount <= o['maxsize']
        ])

        if len(orderfees) == 0:
            return 'No orders at amount ' + str(cj_amount / 1e8)
        fig = plt.figure()
        scale = args.get("scale")
        if (scale is not None) and (scale[0] == "log"):
            orderfees = [float(fee) for fee in orderfees]
            if orderfees[0] > 0:
                ratio = orderfees[-1] / orderfees[0]
                step = ratio**0.0333  # 1/30
                bins = [orderfees[0] * (step**i) for i in range(30)]
            else:
                ratio = orderfees[-1] / 1e-8  # single satoshi placeholder
                step = ratio**0.0333  # 1/30
                bins = [1e-8 * (step**i) for i in range(30)]
                bins[0] = orderfees[0]  # replace placeholder
            plt.xscale('log')
        else:
            bins = 30
        if len(orderfees
               ) == 1:  # these days we have liquidity, but just in case...
            plt.hist(orderfees, bins, rwidth=0.8, range=(0, orderfees[0] * 2))
        else:
            plt.hist(orderfees, bins, rwidth=0.8)
        plt.grid()
        plt.title('CoinJoin Orderbook Depth Chart for amount=' +
                  str(cj_amount / 1e8) + 'btc')
        plt.xlabel('CoinJoin Fee / btc')
        plt.ylabel('Frequency')
        return get_graph_html(fig)
Пример #5
0
    def oid_to_order(self, offer, amount):
        total_amount = amount + offer["txfee"]
        mix_balance = self.wallet.get_balance_by_mixdepth()
        max_mix = max(mix_balance, key=mix_balance.get)

        filtered_mix_balance = [
            m for m in iteritems(mix_balance) if m[1] >= total_amount
        ]
        if not filtered_mix_balance:
            return None, None, None
        jlog.debug('mix depths that have enough = ' +
                   str(filtered_mix_balance))
        filtered_mix_balance = sorted(filtered_mix_balance, key=lambda x: x[0])
        mixdepth = filtered_mix_balance[0][0]
        jlog.info('filling offer, mixdepth=' + str(mixdepth) + ', amount=' +
                  str(amount))

        # mixdepth is the chosen depth we'll be spending from
        cj_addr = self.wallet.get_internal_addr(
            (mixdepth + 1) % (self.wallet.mixdepth + 1),
            jm_single().bc_interface)
        change_addr = self.wallet.get_internal_addr(mixdepth,
                                                    jm_single().bc_interface)

        utxos = self.wallet.select_utxos(mixdepth, total_amount)
        my_total_in = sum([va['value'] for va in utxos.values()])
        real_cjfee = calc_cj_fee(offer["ordertype"], offer["cjfee"], amount)
        change_value = my_total_in - amount - offer["txfee"] + real_cjfee
        if change_value <= jm_single().DUST_THRESHOLD:
            jlog.debug(('change value={} below dust threshold, '
                        'finding new utxos').format(change_value))
            try:
                utxos = self.wallet.select_utxos(
                    mixdepth, total_amount + jm_single().DUST_THRESHOLD)
            except Exception:
                jlog.info('dont have the required UTXOs to make a '
                          'output above the dust threshold, quitting')
                return None, None, None

        return utxos, cj_addr, change_addr
    def oid_to_order(self, offer, amount):
        total_amount = amount + offer["txfee"]
        real_cjfee = calc_cj_fee(offer["ordertype"], offer["cjfee"], amount)
        required_amount = total_amount + \
            jm_single().DUST_THRESHOLD + 1 - real_cjfee

        mix_balance = self.get_available_mixdepths()
        filtered_mix_balance = {
            m: b
            for m, b in mix_balance.items() if b >= required_amount
        }
        if not filtered_mix_balance:
            return None, None, None
        jlog.debug('mix depths that have enough = ' +
                   str(filtered_mix_balance))

        try:
            mixdepth, utxos = self._get_order_inputs(filtered_mix_balance,
                                                     offer, required_amount)
        except NoIoauthInputException:
            jlog.error(
                'unable to fill order, no suitable IOAUTH UTXO found. In '
                'order to spend coins (UTXOs) from a mixdepth using coinjoin,'
                ' there needs to be at least one standard wallet UTXO (not '
                'fidelity bond or different address type).')
            return None, None, None

        jlog.info('filling offer, mixdepth=' + str(mixdepth) + ', amount=' +
                  str(amount))

        cj_addr = self.select_output_address(mixdepth, offer, amount)
        if cj_addr is None:
            return None, None, None
        jlog.info('sending output to address=' + str(cj_addr))

        change_addr = self.wallet_service.get_internal_addr(mixdepth)
        return utxos, cj_addr, change_addr