Ejemplo n.º 1
0
def draw_transactions(state):
    g.viewport_height = state['y'] - 2
    win_transactions = curses.newwin(g.viewport_height, g.x, 1, 0)

    txdata = state['mempool']['transactions']

    g.addstr_rjust(win_transactions, 0, "(UP/DOWN: scroll, ENTER: view, M: refresh)", curses.A_BOLD + curses.color_pair(5), 1)
    # reset cursor if it's been resized off the bottom
    if state['mempool']['cursor'] > state['mempool']['offset'] + (g.viewport_height - 2):
        state['mempool']['offset'] = state['mempool']['cursor'] - (g.viewport_height - 2)

    offset = state['mempool']['offset']

    for index in xrange(offset, offset+g.viewport_height-1):
        if index < len(txdata):
            if index == int(state['mempool']['cursor']):
                win_transactions.addstr(index+1-offset, 1, ">", curses.A_REVERSE + curses.A_BOLD)

            condition = (index == offset+g.viewport_height-2) and (index+1 < len(txdata))
            condition = condition or ( (index == offset) and (index > 0) )

            if condition:
                win_transactions.addstr(index+1-offset, 3, "...")
            else:
                win_transactions.addstr(index+1-offset, 3, "{: 6,d}".format(int(index) + 1) + ": " + txdata[index])

    win_transactions.refresh()
Ejemplo n.º 2
0
def draw_addresses(state):
	g.viewport_heigth = g.y - 5
	win_addresses = curses.newwin(g.viewport_heigth, g.x, 4, 0)
	offset = state['wallet']['offset']

	if 'addresses_view_string' in state['wallet']:

		win_addresses.addstr(0, 1, str(len(state['wallet']['addresses_view_string'])/4) + " addresses:", curses.A_BOLD + curses.color_pair(5))
		g.addstr_rjust(win_addresses, 0, "(UP/DOWN: scroll)", curses.A_BOLD + curses.color_pair(5), 1)
		
		for index in xrange(offset, offset + g.viewport_heigth - 1):
			if index < len(state['wallet']['addresses_view_string']):
					condition = (index == offset + g.viewport_heigth - 2) and (index+1 < len(state['wallet']['addresses_view_string']))
					condition = condition or ( (index == offset) and (index > 0) )

					if condition:
						win_addresses.addstr(index+1-offset, 1, "...")
					else:
						win_addresses.addstr(index+1-offset, 1, state['wallet']['addresses_view_string'][index], curses.color_pair(state['wallet']['addresses_view_colorpair'][index]))

	else:
		g.addstr_cjust(win_addresses, 0, "...waiting for address information being processed...", curses.A_BOLD + curses.color_pair(3))
		# win_addresses.addstr(1, 1, "...waiting for address information being processed...", curses.A_BOLD + curses.color_pair(3))

	win_addresses.refresh()
Ejemplo n.º 3
0
def draw_outputs(state):
    window_height = (g.y - 4) / 2
    win_outputs = curses.newwin(window_height, g.x, 3 + window_height, 0)
    if state['tx']['mode'] == 'outputs':
        win_outputs.addstr(0, 1, "outputs:",
                           curses.A_BOLD + curses.color_pair(3))
        g.addstr_rjust(win_outputs, 0, "(UP/DOWN: scroll)",
                       curses.A_BOLD + curses.color_pair(3), 1)
    else:
        win_outputs.addstr(0, 1, "outputs:",
                           curses.A_BOLD + curses.color_pair(5))
        g.addstr_rjust(win_outputs, 0, "(TAB: switch to)",
                       curses.A_BOLD + curses.color_pair(5), 1)

    offset = state['tx']['out_offset']

    for index in xrange(offset, offset + window_height - 1):
        if index < len(state['tx']['vout_string']):
            condition = (index == offset + window_height -
                         2) and (index + 1 < len(state['tx']['vout_string']))
            condition = condition or ((index == offset) and (index > 0))
            if condition:
                win_outputs.addstr(index + 1 - offset, 1, "... ")
            else:
                string = state['tx']['vout_string'][index]
                if '[UNSPENT]' in string:
                    color = curses.color_pair(1)
                elif '[SPENT]' in string or '[UNCONFIRMED SPEND]' in string:
                    color = curses.color_pair(3)
                else:
                    color = 0
                win_outputs.addstr(index + 1 - offset, 1, string, color)
    win_outputs.refresh()
Ejemplo n.º 4
0
def draw_window(state, window, rpc_queue = None, do_clear = True):

    if do_clear:
        window.clear()
        window.refresh()

    win_header = curses.newwin(3, g.x, 0, 0)

    if 'peerinfo' in state:
        win_header.addstr(0, 1, "Connected peers: " + str(len(state['peerinfo'])), curses.A_BOLD)
        g.addstr_rjust(win_header, 0, "(UP/DOWN: scroll, P: refresh)", curses.A_BOLD, 1)
        win_header.addstr(2, 1, "  Node IP               Version", curses.A_BOLD + curses.color_pair(5))
        header = "Recv MB Sent MB    Time      Height"
        win_header.addstr(2, (g.x - len(header) - 1 if g.x <= 100 else 99 - len(header)), header, curses.A_BOLD + curses.color_pair(5))
        draw_peers(state)

    else:
        if rpc_queue.qsize() > 0:
            g.addstr_cjust(win_header, 0, "...waiting for peer information being processed...", curses.A_BOLD + curses.color_pair(3))
        else:
            win_header.addstr(0, 1, "no peer information loaded.", curses.A_BOLD + curses.color_pair(3))
            win_header.addstr(1, 1, "press 'P' to refresh", curses.A_BOLD)

    win_header.refresh()
    footer.draw_window(state, rpc_queue)
Ejemplo n.º 5
0
def draw_window(state, window, rpc_queue):
    window.clear()
    window.refresh()
    win_header = curses.newwin(1, g.x, 0, 0)

    g.addstr_rjust(win_header, 0, "(G: enter command, E: erase output)",
                   curses.A_BOLD + curses.color_pair(5), 1)
    win_header.refresh()

    if len(state['console']['rbuffer']):
        draw_buffer(state)

    footer.draw_window(state, rpc_queue)
Ejemplo n.º 6
0
def draw_transactions(state):
    g.viewport_height = state['y'] - 6
    win_transactions = curses.newwin(g.viewport_height, g.x, 5, 0)

    height = str(state['blocks']['browse_height'])
    blockdata = state['blocks'][height]
    tx_count = len(blockdata['tx'])
    bytes_per_tx = blockdata['size'] / tx_count

    win_transactions.addstr(
        0, 1, "Transactions: " + "{: 4,d}".format(int(tx_count)) + " (" +
        str(bytes_per_tx) + " bytes/tx)", curses.A_BOLD + curses.color_pair(5))
    g.addstr_rjust(win_transactions, 0, "(UP/DOWN: scroll, ENTER: view)",
                   curses.A_BOLD + curses.color_pair(5), 1)
    # reset cursor if it's been resized off the bottom
    if state['blocks']['cursor'] > state['blocks']['offset'] + (
            g.viewport_height - 2):
        state['blocks']['offset'] = state['blocks']['cursor'] - (
            g.viewport_height - 2)

    offset = state['blocks']['offset']

    for index in xrange(offset, offset + g.viewport_height - 1):
        if index < len(blockdata['tx']):
            if index == state['blocks']['cursor']:
                win_transactions.addstr(index + 1 - offset, 1, ">",
                                        curses.A_REVERSE + curses.A_BOLD)

            condition = (index == offset + g.viewport_height -
                         2) and (index + 1 < len(blockdata['tx']))
            condition = condition or ((index == offset) and (index > 0))

            if condition:
                win_transactions.addstr(index + 1 - offset, 3, "...")
            else:
                win_transactions.addstr(
                    index + 1 - offset, 3, "{: 5d}".format(int(index) + 1) +
                    ": " + blockdata['tx'][index])

    win_transactions.refresh()
Ejemplo n.º 7
0
def draw_window(state, rpc_queue = None, only_work_indicator = False):
    win_footer = curses.newwin(1, g.x, g.y - 1, 0)

    color = curses.color_pair(1)
    if 'testnet' in state:
        if state['testnet']:
            color = curses.color_pair(2)

    if not only_work_indicator:
        x = 1
        for mode_string in g.modes:
            modifier = curses.A_BOLD
            if state['mode'] == mode_string:
                modifier += curses.A_REVERSE
            win_footer.addstr(0, x, mode_string[0].upper(), modifier + curses.color_pair(5)) 
            win_footer.addstr(0, x+1, mode_string[1:], modifier)
            x += len(mode_string) + 2

    if rpc_queue is not None:
        if rpc_queue.qsize() > 0:
            working_indicator = 'wrk... (' + str(rpc_queue.qsize()) + ')'
            g.addstr_rjust(win_footer, 0, working_indicator, curses.A_BOLD + curses.color_pair(3), 1)

    win_footer.refresh()
Ejemplo n.º 8
0
def draw_transactions(state):
	g.viewport_heigth = g.y - 5
	win_transactions = curses.newwin(g.viewport_heigth, g.x, 4, 0)

	win_transactions.addstr(0, 1, "{:,d}".format(len(state['wallet']['view_string'])/(5 if state['wallet']['verbose'] > 0 else 4)) + " transactions:", curses.A_BOLD + curses.color_pair(5))
	caption = "(UP/DOWN: scroll, ENTER: view, V: less verbose)" if state['wallet']['verbose'] > 0 else "(UP/DOWN: scroll, ENTER: view, V: verbose, O: Output tx)"
	g.addstr_rjust(win_transactions, 0, caption, curses.A_BOLD + curses.color_pair(5), 1)
	
	offset = state['wallet']['offset']

	for index in xrange(offset, offset + g.viewport_heigth - 1):
		if index < len(state['wallet']['view_string']):
				condition = (index == offset + g.viewport_heigth - 2) and (index+1 < len(state['wallet']['view_string']))
				condition = condition or ( (index == offset) and (index > 0) )

				if condition:
					win_transactions.addstr(index+1-offset, 1, "...")
				else:
					win_transactions.addstr(index+1-offset, 1, state['wallet']['view_string'][index], curses.color_pair(state['wallet']['view_colorpair'][index]))

				if index == (state['wallet']['cursor']* (5 if state['wallet']['verbose'] > 0 else 4) + 1):
					win_transactions.addstr(index+1-offset, 1, ">", curses.A_REVERSE + curses.A_BOLD)

	win_transactions.refresh()
Ejemplo n.º 9
0
def draw_window(state, window, rpc_queue=None):
    window.clear()
    window.refresh()

    win_header = curses.newwin(4, g.x, 0, 0)

    if 'chaintips' in state:
        win_header.addstr(0, 1, "chain tips: " + str(len(state['chaintips'])),
                          curses.A_BOLD)
        g.addstr_rjust(win_header, 0, "(UP/DOWN: scroll, F: refresh)",
                       curses.A_BOLD)
        win_header.addstr(
            1, 1, "key: Active/Invalid/HeadersOnly/ValidFork/ValidHeaders",
            curses.A_BOLD)
        win_header.addstr(3, 1, "height, length, status, 0-prefix hash",
                          curses.A_BOLD + curses.color_pair(5))
        draw_tips(state)

    else:
        if rpc_queue.qsize() > 0:
            g.addstr_cjust(
                win_header, 0,
                "...waiting for chain tip information being processed...",
                curses.A_BOLD + curses.color_pair(3))
        else:
            win_header.addstr(0, 1, "no chain tip information loaded.",
                              curses.A_BOLD + curses.color_pair(3))
            win_header.addstr(1, 1, "press 'F' to refresh", curses.A_BOLD)
            if g.coin_unit == 'BTC':
                win_header.addstr(
                    2, 1,
                    "(note that bitcoind 0.9.3 and older do not support this feature)",
                    curses.A_BOLD)

    win_header.refresh()
    footer.draw_window(state, rpc_queue)
Ejemplo n.º 10
0
def draw_window(state, window, rpc_queue=None, do_clear = True):

	if do_clear:
		window.clear()
		window.refresh()

	win_header = curses.newwin(3, g.x, 0, 0)

	unit = g.coin_unit
	if 'testnet' in state:
		if state['testnet']:
			unit = g.coin_unit_test

	if 'wallet' in state or 'walletinfo' in state:
		if 'balance' in state:
			balance_string = "Balance: " + "%0.8f" % state['balance'] + " " + unit
			if 'unconfirmedbalance' in state:
				if state['unconfirmedbalance'] != 0:
					balance_string += " (+" + "%0.8f" % state['unconfirmedbalance'] + " unconf)"
			if 'unconfirmed_balance' in state:
				if state['unconfirmed_balance'] != 0:
					balance_string += " (+" + "%0.8f" % state['unconfirmed_balance'] + " unconf)"
			window.addstr(0, 1, balance_string, curses.A_BOLD)
		
		if 'walletinfo' in state:
			if 'paytxfee' in state['walletinfo']:
				fee_string = "Fee: " + "%0.8f" % state['walletinfo']['paytxfee'] + " " + unit + " per kB"
				window.addstr(1, 1, fee_string, curses.A_BOLD)
			fee_string = "Wallet status: "
			if 'unlocked_until' in state['walletinfo']:
				if state['walletinfo']['unlocked_until'] == 0:
					fee_string += 'locked'
					window.addstr(2, 1, fee_string, curses.A_BOLD)
				else:
					try:
						fee_string += 'unlocked until ' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(state['walletinfo']['unlocked_until']))
					except ValueError:
						fee_string += 'unlocked!!! (' + str(state['walletinfo']['unlocked_until'])+ ')'
					window.addstr(2, 1, fee_string, curses.A_BOLD + curses.A_REVERSE)
			else:
				fee_string += 'not encrypted!'
				window.addstr(2, 1, fee_string, curses.A_BOLD + curses.A_REVERSE)

		if state['wallet']['mode'] == 'tx':
			g.addstr_rjust(window, 0, "(W: refresh, A: list addresses, R: new address)", curses.A_BOLD, 1)
			g.addstr_rjust(window, 1, "(X: set tx fee, S: send " + unit + ")", curses.A_BOLD, 1)
			g.addstr_rjust(window, 2, "(E: export all txs, L: export wallet.dat)", curses.A_BOLD, 1)
			draw_transactions(state)
		elif state['wallet']['mode'] == 'settxfee':
			draw_fee_input_window(state, window, rpc_queue)
		elif state['wallet']['mode'] == 'newaddress':
			draw_new_address_window(state, window, rpc_queue)
		elif state['wallet']['mode'] == 'sendtoaddress':
			draw_send_coins_window(state, window, rpc_queue)
		elif state['wallet']['mode'] == 'backupwallet':
			draw_backup_wallet_window(state, window, rpc_queue)
		elif state['wallet']['mode'] == 'exporttx':
			draw_exporttx_window(state, window, rpc_queue)
		else:
			g.addstr_rjust(window, 0, "(W: refresh, A: list addresses, R: new address)", curses.A_BOLD, 1)
			g.addstr_rjust(window, 1, "(X: set tx fee, S: send " + unit + ")", curses.A_BOLD, 1)
			g.addstr_rjust(window, 2, "(E: export all txs, L: export wallet.dat)", curses.A_BOLD, 1)
			draw_addresses(state)

	else:
		if rpc_queue.qsize() > 0:
			g.addstr_cjust(win_header, 0, "...waiting for wallet information being processed...", curses.A_BOLD + curses.color_pair(3))
		else:
			win_header.addstr(0, 1, "no wallet information loaded.", curses.A_BOLD + curses.color_pair(3))
			win_header.addstr(1, 1, "press 'W' to refresh", curses.A_BOLD)

	win_header.refresh()
	footer.draw_window(state, rpc_queue)
Ejemplo n.º 11
0
def draw_window(state, window, rpc_queue=None):
    window.clear()
    window.refresh()
    win_header = curses.newwin(5, g.x, 0, 0)

    if 'browse_height' in state['blocks']:
        height = str(state['blocks']['browse_height'])
        if height in state['blocks']:
            blockdata = state['blocks'][height]

            win_header.addstr(0, 1, "Height: " + "{:,d}".format(int(height)),
                              curses.A_BOLD)
            g.addstr_rjust(
                win_header, 0,
                "(J/K: browse, HOME/END: quicker, L: latest, G: seek)",
                curses.A_BOLD, 1)
            win_header.addstr(1, 1, "Hash: " + blockdata['hash'],
                              curses.A_BOLD)
            win_header.addstr(2, 1, "Root: " + blockdata['merkleroot'],
                              curses.A_BOLD)
            win_header.addstr(
                3, 1,
                str("{:,d}".format(int(blockdata['size']))) + " bytes (" +
                str(blockdata['size'] / 1024) + " KB)       ", curses.A_BOLD)
            g.addstr_cjust(
                win_header, 3,
                "Diff: " + "{:,d}".format(int(blockdata['difficulty'])),
                curses.A_BOLD, 0, 4, 2)
            g.addstr_rjust(
                win_header, 3,
                time.strftime("%Y-%m-%d %H:%M:%S",
                              time.gmtime(blockdata['time'])), curses.A_BOLD,
                1)
            version_bits = "{0:032b}".format(int(blockdata['version']))
            version_bits = version_bits[0:7] + " " + version_bits[
                8:15] + " " + version_bits[16:23] + " " + version_bits[24:]
            win_header.addstr(
                4, 1, "Version: " + str(blockdata['version']) + " (" +
                version_bits + ")", curses.A_BOLD)

            draw_transactions(state)
            state['blocks']['loaded'] = 1

        else:
            if rpc_queue.qsize() > 0:
                g.addstr_cjust(
                    win_header, 0,
                    "...waiting for block information being processed...",
                    curses.A_BOLD + curses.color_pair(3))
            else:
                win_header.addstr(0, 1, "no block information loaded.",
                                  curses.A_BOLD + curses.color_pair(3))
                win_header.addstr(
                    1, 1,
                    "press 'G' to enter a block hash, height, or timestamp",
                    curses.A_BOLD)

    else:
        if rpc_queue.qsize() > 0:
            g.addstr_cjust(
                win_header, 0,
                "...waiting for block information being processed...",
                curses.A_BOLD + curses.color_pair(3))
        else:
            win_header.addstr(0, 1, "no block information loaded.",
                              curses.A_BOLD + curses.color_pair(3))
            win_header.addstr(
                1, 1, "press 'G' to enter a block hash, height, or timestamp",
                curses.A_BOLD)

    win_header.refresh()
    footer.draw_window(state, rpc_queue)
Ejemplo n.º 12
0
def draw_inputs(state):
    window_height = (state['y'] - 4) / 2
    window_width = state['x']
    win_inputs = curses.newwin(window_height, window_width, 3, 0)
    if state['tx']['mode'] == 'inputs':
        win_inputs.addstr(0, 1, "inputs:",
                          curses.A_BOLD + curses.color_pair(3))
        g.addstr_rjust(win_inputs, 0, "(UP/DOWN: select, ENTER: view)",
                       curses.A_BOLD + curses.color_pair(3), 1)
    else:
        win_inputs.addstr(0, 1, "inputs:",
                          curses.A_BOLD + curses.color_pair(5))
        g.addstr_rjust(win_inputs, 0, "(TAB: switch to)",
                       curses.A_BOLD + curses.color_pair(5), 1)

    # reset cursor if it's been resized off the bottom
    if state['tx']['cursor'] > state['tx']['offset'] + (window_height - 2):
        state['tx']['offset'] = state['tx']['cursor'] - (window_height - 2)

    offset = state['tx']['offset']

    for index in xrange(offset, offset + window_height - 1):
        if index < len(state['tx']['vin']):
            if 'txid' in state['tx']['vin'][index]:

                buffer_string = state['tx']['vin'][index][
                    'txid'] + ":" + "%03d" % state['tx']['vin'][index]['vout']
                if 'prev_tx' in state['tx']['vin'][index]:
                    vout = state['tx']['vin'][index]['prev_tx']

                    if 'value' in vout:
                        if vout['scriptPubKey']['type'] == "pubkeyhash":
                            buffer_string = "% 14.8f" % vout[
                                'value'] + ": " + vout['scriptPubKey'][
                                    'addresses'][0].ljust(34)
                        else:
                            if len(vout['scriptPubKey']
                                   ['asm']) > window_width - 37:
                                buffer_string = "% 14.8f" % vout[
                                    'value'] + ": ..." + vout['scriptPubKey'][
                                        'asm'][-(window_width - 40):]
                            else:
                                buffer_string = "% 14.8f" % vout[
                                    'value'] + ": " + vout['scriptPubKey'][
                                        'asm']

                        length = len(buffer_string)
                        if length + 72 < window_width:
                            buffer_string += " " + state['tx']['vin'][index][
                                'txid'] + ":" + "%03d" % state['tx']['vin'][
                                    index]['vout']
                        else:
                            buffer_string += " " + state['tx']['vin'][index][
                                'txid'][:(window_width - length -
                                          14)] + "[...]:" + "%03d" % state[
                                              'tx']['vin'][index]['vout']

                if index == (state['tx']['cursor']):
                    win_inputs.addstr(index + 1 - offset, 1, ">",
                                      curses.A_REVERSE + curses.A_BOLD)

                condition = (index == offset + window_height -
                             2) and (index + 1 < len(state['tx']['vin']))
                condition = condition or ((index == offset) and (index > 0))
                if condition:
                    win_inputs.addstr(index + 1 - offset, 3, "...")
                else:
                    win_inputs.addstr(index + 1 - offset, 3, buffer_string)

            elif 'coinbase' in state['tx']['vin'][index]:
                coinbase = "[coinbase] " + state['tx']['vin'][index]['coinbase']
                coinbase_string = " [strings] " + binascii.unhexlify(
                    state['tx']['vin'][index]['coinbase'])

                # strip non-ASCII characters
                coinbase_string = ''.join(
                    [x for x in coinbase_string if 31 < ord(x) < 127])

                if len(coinbase) > window_width - 1:
                    win_inputs.addstr(index + 1 - offset, 1,
                                      coinbase[:window_width - 5] + " ...")
                else:
                    win_inputs.addstr(index + 1 - offset, 1,
                                      coinbase[:window_width - 1])

                if len(coinbase_string) > window_width - 1:
                    win_inputs.addstr(
                        index + 2 - offset, 1,
                        coinbase_string[:window_width - 5] + " ...")
                else:
                    win_inputs.addstr(index + 2 - offset, 1,
                                      coinbase_string[:window_width - 1])

    win_inputs.refresh()
Ejemplo n.º 13
0
def draw_window(state, window, rpc_queue):
    # TODO: add transaction locktime, add sequence to inputs
    window.clear()
    window.refresh()
    win_header = curses.newwin(3, g.x, 0, 0)

    unit = g.coin_unit
    if g.testnet:
        unit = g.coin_unit_test
    if 'tx' in state:
        win_header.addstr(0, 1, "txid: " + state['tx']['txid'], curses.A_BOLD)
        win_header.addstr(
            1, 1,
            str(state['tx']['size']) + " bytes (" +
            "{:.2f}".format(float(state['tx']['size']) / 1024.0) +
            " KB)       ", curses.A_BOLD)

        if 'total_outputs' in state['tx']:
            output_string = "%.8f" % state['tx']['total_outputs'] + " " + unit
            if 'total_inputs' in state['tx']:
                if state['tx']['total_inputs'] == 'coinbase':
                    fee = float(0)
                    output_string += " (coinbase)"
                else:  # Verbose mode only
                    try:
                        if float(state['tx']['total_inputs']) == 0:
                            fee = float(0)
                        else:
                            fee = float(state['tx']['total_inputs']) - float(
                                state['tx']['total_outputs'])
                    except:
                        fee = float(state['tx']['total_inputs']) - float(
                            state['tx']['total_outputs'])
                    output_string += " + " + "%.8f" % fee + " " + unit + " fee"
            else:
                output_string += " + unknown fee"
            win_header.addstr(1, 26, output_string.rjust(45), curses.A_BOLD)

        if 'time' in state['tx']:
            output_string = time.strftime("%Y-%m-%d %H:%M:%S",
                                          time.localtime(state['tx']['time']))
        else:
            output_string = ""
        if 'confirmations' in state['tx']:
            output_string += ("" if not len(output_string) else
                              " / ") + "{:,d}".format(
                                  int(state['tx']['confirmations'])) + " conf"
        else:
            output_string += ("" if not len(output_string) else
                              " / ") + "unconfirmed"
        win_header.addstr(2, 1, output_string[:g.x - 2], curses.A_BOLD)

        history_height = 0 if not 'txid_history' in state else len(
            state['txid_history']) - 1
        if history_height <= 0:
            history_msg = ""
        else:
            if g.x > 79:
                history_msg = ", J: browse back"
            else:
                history_msg = ", J: go back"
        g.addstr_rjust(win_header, 2,
                       "(V: verbose, G: enter txid" + history_msg + ")",
                       curses.A_BOLD, 1)

        draw_inputs(state)
        draw_outputs(state)

    else:
        if rpc_queue.qsize() > 0:
            g.addstr_cjust(
                win_header, 0,
                "...waiting for transaction information being processed...",
                curses.A_BOLD + curses.color_pair(3))
        else:
            win_header.addstr(
                0, 1,
                "no transaction loaded or no transaction information found.",
                curses.A_BOLD + curses.color_pair(3))
            win_header.addstr(
                1, 1, "if you have entered one, consider running " +
                g.rpc_deamon + " with -txindex", curses.A_BOLD)
            win_header.addstr(2, 1, "press 'G' to enter a txid", curses.A_BOLD)

    win_header.refresh()
    footer.draw_window(state, rpc_queue)
Ejemplo n.º 14
0
def draw_window(state, old_window, rpc_queue, do_clear = True):

    window = curses.newwin(g.y - 1, g.x, 0, 0)

    if do_clear:
        old_window.clear()
        old_window.refresh()

    # display load average
    load_avg = os.getloadavg()
    g.addstr_rjust(window, 1, "Load avg: " + "{:.2f}".format(load_avg[0]) + " / " + "{:.2f}".format(load_avg[1]) + " / " + "{:.2f}".format(load_avg[2]), curses.A_BOLD, 1)

    # pad lines are optionial - depending on window size
    padline = [1, 1, 1, 1]
    (this_y, this_x) = window.getmaxyx()
    if this_y <= 15:
        padline[3] = 0
    if this_y <= 14:
        padline[2] = 0
    if this_y <= 13:
        padline[1] = 0
    if this_y <= 12:
        padline[0] = 0


    if 'version' in state:
        if state['testnet'] == 1:
            g.testnet = True;
            color = curses.color_pair(2)
            window.addstr(1, 1, g.rpc_deamon + " v" + state['version'] + " (TESTNET)", color + curses.A_BOLD)
            unit = g.coin_unit_test
        else:
            g.testnet = False;
            color = curses.color_pair(1)
            window.addstr(1, 1, g.rpc_deamon + " v" + state['version'] + " ", color + curses.A_BOLD)
            unit = g.coin_unit
        window.addstr(0, 1, g.rpc_deamon + "-ncurses " + g.version, color + curses.A_BOLD)

    if 'peers' in state:
        if state['peers'] > 0:
            color = 0
        else:
            color = curses.color_pair(3)
        g.addstr_ljust(window, 0, str(state['peers']) + " peers", color + curses.A_BOLD, 0, 10, 4)
        
    if 'balance' in state and g.wallet_support:
        balance_string = "%0.8f" % state['balance'] + " " + unit
        if 'unconfirmedbalance' in state:
            if state['unconfirmedbalance'] != 0:
                balance_string += " (+" + "%0.8f" % state['unconfirmedbalance'] + " unconf)"
        g.addstr_ljust(window, 1, balance_string, curses.A_BOLD, 0, 10, 4)
    else:
        g.addstr_ljust(window, 1, "- wallet disabled -", curses.A_BOLD, 0, 10, 4)
        
    if 'mininginfo' in state:
        height = str(state['mininginfo']['blocks'])
        if height in state['blocks']:
            blockdata = state['blocks'][str(height)]

            if 'new' in blockdata:
                window.attrset(curses.A_REVERSE + curses.color_pair(5) + curses.A_BOLD)
                blockdata.pop('new')

            window.addstr(2 + padline[0], 1, "{:7d}".format(int(height)) + ": " + str(blockdata['hash']))
            window.addstr(3 + padline[0], 1, "{:,d}".format(int(blockdata['size'])) + " bytes (" + "{:,.2f}".format(float(blockdata['size']/1024)) + " KB)       ")
            tx_count = len(blockdata['tx'])
            bytes_per_tx = blockdata['size'] / tx_count
            window.addstr(4 + padline[0], 1, "Transactions: " + "{:,d}".format(int(tx_count)) + " (" + "{:,d}".format(int(bytes_per_tx)) + " bytes/tx)")

            if 'coinbase_amount' in blockdata:
                block_subsidy = float(float(g.reward_base) / (2 ** (state['mininginfo']['blocks'] // g.halving_blockamount)))
                
                if block_subsidy:
                    coinbase_amount = float(blockdata['coinbase_amount'])
                    total_fees = float(coinbase_amount) - block_subsidy # assumption, mostly correct

                    if coinbase_amount > 0:
                        fee_percentage = "%0.2f" % ((total_fees / coinbase_amount) * 100)
                        coinbase_amount_str = "%0.8f" % coinbase_amount
                        window.addstr(5 + padline[0] + padline[1], 1, "Total block reward: " + coinbase_amount_str + " " + unit + " (" + str(block_subsidy) + " " + unit + " +" + fee_percentage + "% fees)")

                    if tx_count > 1:
                        tx_count -= 1 # the coinbase can't pay a fee
                        fees_per_tx = (total_fees / tx_count) * 1000
                        fees_per_kb = ((total_fees * 1024) / blockdata['size']) * 1000
                        total_fees_str = "%0.8f" % total_fees + " " + unit
                        fees_per_tx = "%0.5f" % fees_per_tx + " m" + unit + "/tx"
                        fees_per_kb = "%0.5f" % fees_per_kb + " m" + unit + "/KB"
                        window.addstr(6 + padline[0] + padline[1], 1, "Fees: " + total_fees_str + " (avg " +  fees_per_tx + ", ~" + fees_per_kb + ")")


            g.addstr_rjust(window, 3 + padline[0], "Block timestamp: " + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(blockdata['time'])), curses.A_NORMAL, 1)
            
            if state['lastblocktime'] == 0:
                recvdelta_string = "        "
            else:
                recvdelta = int(time.time() - state['lastblocktime'])
                m, s = divmod(recvdelta, 60)
                h, m = divmod(m, 60)
                recvdelta_string = "{:02d}:{:02d}:{:02d}".format(h,m,s)

            stampdelta = int(time.time() - blockdata['time'])
            if stampdelta > 3600*3: # probably syncing if it's three hours old
                stampdelta_string = "             (syncing)"
            elif stampdelta > 0:
                m, s = divmod(stampdelta, 60)
                h, m = divmod(m, 60)
                d, h = divmod(h, 24)
                stampdelta_string = "({:d}d {:02d}:{:02d}:{:02d} by stamp)".format(d,h,m,s)
            else:
                stampdelta_string = "     (stamp in future)"

            g.addstr_rjust(window, 4 + padline[0], "Age: " + recvdelta_string + " " + stampdelta_string, curses.A_NORMAL, 1)

            if 'chainwork' in blockdata:
                log2_chainwork = math.log(int(blockdata['chainwork'], 16), 2)
                try:
                    window.addstr(10 + padline[0] + padline[1] + padline[2] + padline[3], 1, "Chain work: 2**" + "%0.6f" % log2_chainwork)
                except:
                    pass

        diff = int(state['mininginfo']['difficulty'])
        window.addstr(7 + padline[0] + padline[1] + padline[2], 1, "Diff:        " + "{:,d}".format(diff))

    for block_avg in state['networkhashps']:
        index = 7 + padline[0] + padline[1] + padline[2]

        if block_avg == 'diff':
            pass
        elif block_avg == 2016:
            index += 1
        elif block_avg == g.blocks_per_day:
            index += 2
        else:
            break

        rate = state['networkhashps'][block_avg]
        if block_avg != 'diff':
            nextdiff = (rate*600)/(2**32)
            if state['testnet'] == 1:
                nextdiff *= 2 # testnet has 1200 est. block interval, not 600
            try:
                window.addstr(index, 1, "Est (" + str(block_avg).rjust(4) + "): ~" + "{:,d}".format(int(nextdiff)))
            except:
                window.addstr(index, 1, "Est (" + str(block_avg).rjust(4) + "): ~" + "{:,d}".format(int(nextdiff)))

        if rate > 10**18:
            rate /= 10**18
            suffix = " EH/s"
        elif rate > 10**12:
            rate /= 10**12
            suffix = " TH/s"
        else:
            rate /= 10**6
            suffix = " MH/s"
        try:
            rate_string = "{:9.4f}".format(float(rate)) + suffix
            g.addstr_rjust(window, index, "Hashrate (" + str(block_avg).rjust(4) + "): " + rate_string.rjust(13), curses.A_NORMAL, 1)
        except:
            g.addstr_rjust(window, index, "Hashrate (" + str(block_avg).rjust(4) + "): ?????????????", curses.A_NORMAL, 1)
        index += 1

        pooledtx = state['mininginfo']['pooledtx']
        g.addstr_rjust(window, 10 + padline[0] + padline[1] + padline[2] + padline[3], "Mempool transactions: " + "{:5,d}".format(int(pooledtx)), curses.A_NORMAL, 1)
        
    if 'totalbytesrecv' in state:
        recvmb = "{:,.2f}".format(float(state['totalbytesrecv']*1.0/1048576))
        sentmb = "{:,.2f}".format(float(state['totalbytessent']*1.0/1048576))
        recvsent_string = "D/U: " + recvmb + " / " + sentmb + " MB"
        g.addstr_rjust(window, 0, recvsent_string, curses.A_BOLD, 1)

    if 'estimatefee' in state:
        string = "estimatefee:"
        for item in state['estimatefee']:
            if item['value'] > 0:
                string += " (" + str(item['blocks']) + ")" + "%4.2f" % (item['value']*1000) + " m" + unit
        if len(string) > 12:
            g.addstr_rjust(window, 11 + padline[0] + padline[1] + padline[2] + padline[3], string, curses.A_NORMAL, 1)

    if 'mininginfo' in state:
        if 'errors' in state['mininginfo']:
            errors = state['mininginfo']['errors']
        else:
            errors = state['mininginfo']['warnings']
        if len(errors):
            try:
                y = this_y-1
                window.addstr(y, 1, errors[:g.x - 1], curses.color_pair(5) + curses.A_BOLD + curses.A_REVERSE)
            except:
                pass

    window.refresh()
    footer.draw_window(state, rpc_queue)