Beispiel #1
0
    def richlist(self, data=None):
        """
        only feasible while chain is small..
        :param data:
        :return:
        """
        logger.info('<<< API richlist call')

        if not data:
            data = 5

        error = {
            'status': 'error',
            'error': 'invalid argument',
            'method': 'richlist',
            'parameter': data
        }

        try:
            n = int(data)
        except:
            return json_print_telnet(error)

        if n <= 0 or n > 20:
            return json_print_telnet(error)

        if not self.factory.state.state_uptodate(
                self.factory.chain.m_blockheight()):
            return json_print_telnet({
                'status': 'error',
                'error': 'leveldb failed',
                'method': 'richlist'
            })

        addr = self.factory.state.return_all_addresses()
        richlist = sorted(addr, key=itemgetter(1), reverse=True)

        rl = {'richlist': {}}

        if len(richlist) < n:
            n = len(richlist)

        for rich in richlist[:n]:
            rl['richlist'][richlist.index(rich) + 1] = {}
            rl['richlist'][richlist.index(rich) +
                           1]['address'] = rich[0].decode()
            rl['richlist'][richlist.index(rich) +
                           1]['balance'] = self._format_qrlamount(rich[1])

        rl['status'] = 'ok'

        return json_print_telnet(rl)
Beispiel #2
0
    def last_block(self, data=None):
        logger.info('<<< API last_block call')

        error = {
            'status': 'error',
            'error': 'invalid argument',
            'method': 'last_block',
            'parameter': data
        }

        if not data:
            data = 1

        try:
            n = int(data)
        except:
            return json_print_telnet(error)

        if n <= 0 or n > 20:
            return json_print_telnet(error)

        lb = []
        beginning = self.factory.chain.height() - n
        for blocknum in range(self.factory.chain.height(), beginning - 1, -1):
            block = self.factory.chain.m_get_block(blocknum)
            lb.append(block)

        last_blocks = {'blocks': []}
        i = 0
        for block in lb[1:]:
            i += 1
            tmp_block = {
                'blocknumber':
                block.blockheader.blocknumber,
                'block_reward':
                self._format_qrlamount(block.blockheader.block_reward),
                'blockhash':
                bin2hstr(block.blockheader.prev_blockheaderhash),
                'timestamp':
                block.blockheader.timestamp,
                'block_interval':
                lb[i - 1].blockheader.timestamp - block.blockheader.timestamp,
                'number_transactions':
                len(block.transactions)
            }

            last_blocks['blocks'].append(tmp_block)

        last_blocks['status'] = 'ok'

        return json_print_telnet(last_blocks)
Beispiel #3
0
    def richlist(self, n=None):
        """
        only feasible while chain is small..
        :param n:
        :return:
        """
        if not n:
            n = 5

        error = {
            'status': 'error',
            'error': 'invalid argument',
            'method': 'richlist',
            'parameter': n
        }

        try:
            n = int(n)
        except:
            return json_print_telnet(error)

        if n <= 0 or n > 20:
            return json_print_telnet(error)

        if not self.state.state_uptodate(self.m_blockheight()):
            return json_print_telnet({
                'status': 'error',
                'error': 'leveldb failed',
                'method': 'richlist'
            })

        addr = self.state.db.return_all_addresses()
        richlist = sorted(addr, key=itemgetter(1), reverse=True)

        rl = {'richlist': {}}

        if len(richlist) < n:
            n = len(richlist)

        for rich in richlist[:n]:
            rl['richlist'][richlist.index(rich) + 1] = {}
            rl['richlist'][richlist.index(rich) + 1]['address'] = rich[0]
            rl['richlist'][richlist.index(rich) +
                           1]['balance'] = rich[1] / 100000000.000000000

        rl['status'] = 'ok'

        return json_print_telnet(rl)
Beispiel #4
0
 def empty(self, data=None):
     error = {
         'status': 'error',
         'error': 'no method supplied',
         'methods available': self.api_list
     }
     return json_print_telnet(error)
Beispiel #5
0
    def last_block(self, n=1):

        error = {
            'status': 'error',
            'error': 'invalid argument',
            'method': 'last_block',
            'parameter': n
        }

        try:
            n = int(n)
        except:
            return json_print_telnet(error)

        if n <= 0 or n > 20:
            return json_print_telnet(error)

        lb = []
        beginning = self.height() - n
        for blocknum in range(self.height(), beginning - 1, -1):
            block = self.m_get_block(blocknum)
            lb.append(block)

        last_blocks = {'blocks': []}
        i = 0
        for block in lb[1:]:
            i += 1
            tmp_block = {
                'blocknumber':
                block.blockheader.blocknumber,
                'block_reward':
                block.blockheader.block_reward / 100000000.00000000,
                'blockhash':
                block.blockheader.prev_blockheaderhash,
                'timestamp':
                block.blockheader.timestamp,
                'block_interval':
                lb[i - 1].blockheader.timestamp - block.blockheader.timestamp,
                'number_transactions':
                len(block.transactions)
            }

            last_blocks['blocks'].append(tmp_block)

        last_blocks['status'] = 'ok'

        return json_print_telnet(last_blocks)
Beispiel #6
0
    def basic_info(self, address):
        addr = {}

        if not self.state.state_address_used(address):
            addr['status'] = 'error'
            addr['error'] = 'Address not found'
            addr['parameter'] = address
            return json_print_telnet(addr)

        nonce, balance, _ = self.state.state_get_address(address)
        addr['state'] = {}
        addr['state']['address'] = address
        addr['state']['balance'] = balance / 100000000.000000000
        addr['state']['nonce'] = nonce
        addr['state']['transactions'] = self.state.state_get_txn_count(address)
        addr['status'] = 'ok'
        return json_print_telnet(addr)
Beispiel #7
0
    def last_tx(self, data=None):
        logger.info('<<< API last_tx call')

        if not data:
            data = 1

        addr = {'transactions': []}

        error = {
            'status': 'error',
            'error': 'invalid argument',
            'method': 'last_tx',
            'parameter': data
        }

        try:
            n = int(data)
        except:
            return json_print_telnet(error)

        if n <= 0 or n > 20:
            return json_print_telnet(error)

        try:
            last_txn = self.factory.state.db.get('last_txn')
        except Exception:
            error['error'] = 'txnhash not found'
            return json_print_telnet(error)

        n = min(len(last_txn), n)
        while n > 0:
            n -= 1
            tx_meta = last_txn[n]
            tx = SimpleTransaction().json_to_transaction(tx_meta[0])
            tmp_txn = {
                'txhash': bin2hstr(tx.txhash),
                'block': tx_meta[1],
                'timestamp': tx_meta[2],
                'amount': self._format_qrlamount(tx.amount),
                'type': tx.subtype
            }

            addr['transactions'].append(tmp_txn)
            addr['status'] = 'ok'

        return json_print_telnet(addr)
Beispiel #8
0
    def ping(self, data=None):
        logger.info('<<< API network latency ping call')
        self.factory.pos.p2pFactory.ping_peers()  # triggers ping for all connected peers at timestamp now. after pong response list is collated. previous list is delivered.

        pings = {'status': 'ok',
                 'peers': self.factory.chain.ping_list}

        return json_print_telnet(pings)
Beispiel #9
0
    def stats(self, data=None):
        logger.info('<<< API stats call')

        # FIXME: Review all this. Most math is flawed

        # calculate staked/emission %
        total_at_stake = 0
        total_supply = self.factory.state.total_coin_supply()

        for staker in self.factory.state.stake_validators_list.sv_list:
            total_at_stake += self.factory.state.state_balance(staker)

        staked = 100 * total_at_stake / total_supply

        # calculate average blocktime over last 100 blocks..
        z = 0
        t = []

        last_n_block = 100

        last_block = self.factory.chain.m_blockchain[-1]
        for _ in range(last_n_block):
            if last_block.blockheader.blocknumber <= 0:
                break
            prev_block = self.factory.chain.m_get_block(last_block.blockheader.blocknumber - 1)
            x = last_block.blockheader.timestamp - prev_block.blockheader.timestamp
            last_block = prev_block
            t.append(x)
            z += x

        block_one = self.factory.chain.m_get_block(1)
        network_uptime = 0
        if block_one:
            network_uptime = time.time() - block_one.blockheader.timestamp

        block_time = 0
        block_time_variance = 0
        if len(t) > 0:
            block_time = z / len(t)
            block_time_variance = max(t) - min(t)   # FIXME: This is not the variance!

        net_stats = {'status': 'ok', 'version': config.dev.version_number,
                     'block_reward': self.factory.format_qrlamount(self.factory.chain.m_blockchain[-1].blockheader.block_reward),
                     'stake_validators': len(self.factory.chain.state.stake_validators_list.sv_list),
                     'epoch': self.factory.chain.m_blockchain[-1].blockheader.epoch,
                     'staked_percentage_emission': staked, 'network': 'qrl testnet',
                     'network_uptime': network_uptime,
                     'block_time': block_time,
                     'block_time_variance': block_time_variance,
                     'blockheight': self.factory.chain.m_blockheight(),
                     'nodes': len(self.factory.peers) + 1,
                     # FIXME: Magic number? Unify
                     'emission': self._format_qrlamount(self.factory.state.total_coin_supply()),
                     'unmined': config.dev.total_coin_supply - float(self._format_qrlamount(self.factory.state.total_coin_supply()))}

        return json_print_telnet(net_stats)
Beispiel #10
0
    def ip_geotag(self, data=None):

        ip = {'status': 'ok', 'ip_geotag': self.ip_list}

        x = 0
        for i in self.ip_list:
            ip['ip_geotag'][x] = i
            x += 1

        return json_print_telnet(ip)
Beispiel #11
0
    def parse_cmd(self, data):

        data = data.split()  # typical request will be: "GET /api/{command}/{parameter} HTTP/1.1"

        if len(data) == 0:
            return

        if data[0] != b'GET' and data[0] != b'OPTIONS':
            return False

        if data[0] == b'OPTIONS':
            http_header_OPTIONS = ("HTTP/1.1 200 OK\r\n"
                                   "Access-Control-Allow-Origin: *\r\n"
                                   "Access-Control-Allow-Methods: GET\r\n"
                                   "Access-Control-Allow-Headers: x-prototype-version,x-requested-with\r\n"
                                   "Content-Length: 0\r\n"
                                   "Access-Control-Max-Age: 2520\r\n"
                                   "\r\n")
            self.transport.write(http_header_OPTIONS)
            return

        data = data[1].decode('ascii')[1:].split('/')

        if data[0].lower() != 'api':
            return False

        if len(data) == 1:
            data.append('')

        if data[1] == '':
            data[1] = 'empty'

        if data[1].lower() not in self.api_list:  # supported {command} in api_list
            error = {'status': 'error', 'error': 'supported method not supplied', 'parameter': data[1]}
            self.transport.write(json_print_telnet(error))
            return False

        api_call = getattr(self, data[1].lower())

        if len(data) < 3:
            json_txt = api_call()
        else:
            json_txt = api_call(data[2])

        http_header_GET = ("HTTP/1.1 200 OK\r\n"
                           "Content-Type: application/json\r\n"
                           "Content-Length: %s\r\n"
                           "Access-Control-Allow-Headers: x-prototype-version,x-requested-with\r\n"
                           "Access-Control-Max-Age: 2520\r\n"
                           "Access-Control-Allow-Origin: *\r\n"
                           "Access-Control-Allow-Methods: GET\r\n"
                           "\r\n") % (str(len(json_txt)))

        self.transport.write(bytes(http_header_GET + json_txt, 'utf-8'))
        return
Beispiel #12
0
    def _json_block(self, args):
        if not args:
            self.output['message'].write(
                helper.json_print_telnet(self.factory.chain.m_get_last_block())
                + '\r\n')
            return True
        try:
            int(args[0])
        except:
            self.output['message'].write(
                '>>> Try "json_block <block number>" \r\n')
            return True

        if int(args[0]) > self.factory.chain.m_blockheight():
            self.output['message'].write('>>> Block > Blockheight\r\n')
            return True
        self.output['status'] = 0
        self.output['message'].write(
            helper.json_print_telnet(
                self.factory.chain.m_get_block(int(args[0]))) + '\r\n')
Beispiel #13
0
    def ip_geotag(self, data=None):
        logger.info('<<< API ip_geotag call')
        self.factory.pos.p2pFactory.ip_geotag_peers()
        ip = {'status': 'ok', 'ip_geotag': self.factory.chain.ip_list}

        x = 0
        for i in self.factory.chain.ip_list:
            ip['ip_geotag'][x] = i
            x += 1

        return json_print_telnet(ip)
Beispiel #14
0
    def last_tx(self, n=1):

        addr = {'transactions': []}
        error = {
            'status': 'error',
            'error': 'invalid argument',
            'method': 'last_tx',
            'parameter': n
        }

        try:
            n = int(n)
        except:
            return json_print_telnet(error)

        if n <= 0 or n > 20:
            return json_print_telnet(error)

        try:
            last_txn = self.state.db.get('last_txn')
        except Exception:
            error['error'] = 'txnhash not found'
            return json_print_telnet(error)

        n = min(len(last_txn), n)
        while n > 0:
            n -= 1
            tx_meta = last_txn[n]
            tx = SimpleTransaction().json_to_transaction(tx_meta[0])
            tmp_txn = {
                'txhash': tx.txhash,
                'block': tx_meta[1],
                'timestamp': tx_meta[2],
                'amount': tx.amount / 100000000.000000000,
                'type': tx.subtype
            }

            addr['transactions'].append(tmp_txn)
            addr['status'] = 'ok'

        return json_print_telnet(addr)
Beispiel #15
0
    def stake_reveal_ones(self, data=None):

        sr = {'status': 'ok', 'reveals': {}}

        for c in self.stake_reveal_one:
            sr['reveals'][str(c[1]) + '-' + str(c[2])] = {}
            sr['reveals'][str(c[1]) + '-' + str(c[2])]['stake_address'] = c[0]
            sr['reveals'][str(c[1]) + '-' + str(c[2])]['block_number'] = c[2]
            sr['reveals'][str(c[1]) + '-' + str(c[2])]['headerhash'] = c[1]
            sr['reveals'][str(c[1]) + '-' + str(c[2])]['reveal'] = c[3]

        return json_print_telnet(sr)
Beispiel #16
0
    def last_unconfirmed_tx(self, data=None):
        logger.info('<<< API last_unconfirmed_tx call')

        addr = {'transactions': []}
        error = {
            'status': 'error',
            'error': 'invalid argument',
            'method': 'last_tx',
            'parameter': data
        }

        if not data:
            data = 1
        try:
            n = int(data)
        except:
            return json_print_telnet(error)

        if n <= 0 or n > 20:
            return json_print_telnet(error)

        tx_num = len(self.factory.chain.transaction_pool)
        while tx_num > 0:
            tx_num -= 1
            tx = self.factory.chain.transaction_pool[tx_num]
            if tx.subtype != TX_SUBTYPE_TX:
                continue
            tmp_txn = {
                'txhash': bin2hstr(tx.txhash),
                'block': 'unconfirmed',
                'timestamp': 'unconfirmed',
                'amount': self._format_qrlamount(tx.amount),
                'type': tx.subtype
            }

            tmp_txn['type'] = Transaction.tx_id_to_name(tmp_txn['type'])
            addr['transactions'].append(tmp_txn)

        addr['status'] = 'ok'
        return json_print_telnet(addr)
Beispiel #17
0
    def search_txhash(self, txhash):  # txhash is unique due to nonce.
        err = {
            'status': 'Error',
            'error': 'txhash not found',
            'method': 'txhash',
            'parameter': txhash
        }
        for tx in self.transaction_pool:
            if tx.txhash == txhash:
                logger.info('%s found in transaction pool..', txhash)
                tx_new = copy.deepcopy(tx)
                tx_new.block = 'unconfirmed'
                tx_new.hexsize = len(json_bytestream(tx_new))
                tx_new.status = 'ok'
                return json_print_telnet(tx_new)

        try:
            txn_metadata = self.state.db.get(txhash)
        except:
            logger.info(
                '%s does not exist in memory pool or local blockchain..',
                txhash)
            return json_print_telnet(err)

        json_tx = json.loads(txn_metadata[0])
        if json_tx['subtype'] == transaction.TX_SUBTYPE_TX:
            tx = SimpleTransaction().json_to_transaction(txn_metadata[0])
        elif json_tx['subtype'] == transaction.TX_SUBTYPE_COINBASE:
            tx = CoinBase().json_to_transaction(txn_metadata[0])
        tx_new = copy.deepcopy(tx)
        tx_new.block = txn_metadata[1]
        tx_new.timestamp = txn_metadata[2]
        tx_new.confirmations = self.m_blockheight() - txn_metadata[1]
        tx_new.hexsize = len(json_bytestream(tx_new))
        tx_new.amount = tx_new.amount / 100000000.000000000
        if json_tx['subtype'] == transaction.TX_SUBTYPE_TX:
            tx_new.fee = tx_new.fee / 100000000.000000000
        logger.info('%s found in block %s', txhash, str(txn_metadata[1]))
        tx_new.status = 'ok'
        return json_print_telnet(tx_new)
Beispiel #18
0
    def stake_commits(self, data=None):

        sc = {'status': 'ok', 'commits': {}}

        for c in self.stake_commit:
            # [stake_address, block_number, merkle_hash_tx, commit_hash]
            sc['commits'][str(c[1]) + '-' + c[3]] = {}
            sc['commits'][str(c[1]) + '-' + c[3]]['stake_address'] = c[0]
            sc['commits'][str(c[1]) + '-' + c[3]]['block_number'] = c[1]
            sc['commits'][str(c[1]) + '-' + c[3]]['merkle_hash_tx'] = c[2]
            sc['commits'][str(c[1]) + '-' + c[3]]['commit_hash'] = c[3]

        return json_print_telnet(sc)
Beispiel #19
0
    def stake_reveals(self, data=None):

        sr = {'status': 'ok', 'reveals': {}}

        # chain.stake_reveal.append([stake_address, block_number, merkle_hash_tx, reveal])
        for c in self.stake_reveal:
            sr['reveals'][str(c[1]) + '-' + c[3]] = {}
            sr['reveals'][str(c[1]) + '-' + c[3]]['stake_address'] = c[0]
            sr['reveals'][str(c[1]) + '-' + c[3]]['block_number'] = c[1]
            sr['reveals'][str(c[1]) + '-' + c[3]]['merkle_hash_tx'] = c[2]
            sr['reveals'][str(c[1]) + '-' + c[3]]['reveal'] = c[3]

        return json_print_telnet(sr)
Beispiel #20
0
    def balance(self, data=None):
        logger.info('<<< API balance call %s', data)

        address = data

        addr = {}

        if not self.factory.state.state_address_used(address):
            addr['status'] = 'error'
            addr['error'] = 'Address not found'
            addr['parameter'] = address
            return json_print_telnet(addr)

        nonce, balance, _ = self.factory.state.state_get_address(address)
        addr['state'] = {}
        addr['state']['address'] = address
        addr['state']['balance'] = balance / 100000000.000000000
        addr['state']['nonce'] = nonce
        addr['state']['transactions'] = self.factory.state.state_get_txn_count(
            address)
        addr['status'] = 'ok'

        return json_print_telnet(addr)
Beispiel #21
0
    def next_stakers(self, data=None):
        # (stake -> address, hash_term, nonce)
        next_stakers = {'status': 'ok', 'stake_list': []}

        for s in self.state.next_stake_list_get():
            tmp_stakers = {
                'address': s[0],
                'balance': self.state.state_balance(s[0]) / 100000000.00000000,
                'hash_terminator': s[1],
                'nonce': s[2]
            }

            next_stakers['stake_list'].append(tmp_stakers)

        return json_print_telnet(next_stakers)
Beispiel #22
0
    def stakers(self, data=None):
        logger.info('<<< API stakers call')

        stakers = {'status': 'ok',
                   'stake_list': []}

        for staker in self.factory.state.stake_validators_list.sv_list:
            sv = self.factory.state.stake_validators_list.sv_list[staker]
            tmp_stakers = {'address': sv.stake_validator,
                           'balance': self.factory.format_qrlamount(sv.balance),
                           'hash_terminator': [],
                           'nonce': sv.nonce}

            for i in range(len(sv.hashchain_terminators)):
                tmp_stakers['hash_terminator'].append(bin2hstr(sv.hashchain_terminators[i]))

            stakers['stake_list'].append(tmp_stakers)

        return json_print_telnet(stakers)
Beispiel #23
0
    def search_address(self, address):

        addr = {'transactions': []}

        txnhash_added = set()

        if not self.state.state_address_used(address):
            addr['status'] = 'error'
            addr['error'] = 'Address not found'
            addr['parameter'] = address
            return json_print_telnet(addr)

        nonce, balance, pubhash_list = self.state.state_get_address(address)
        addr['state'] = {}
        addr['state']['address'] = address
        addr['state']['balance'] = balance / 100000000.000000000
        addr['state']['nonce'] = nonce

        for s in self.state.stake_list_get():
            if address == s[0]:
                addr['stake'] = {}
                addr['stake']['selector'] = s[2]
                # pubhashes used could be put here..

        tmp_transactions = []
        for tx in self.transaction_pool:
            if tx.subtype not in (transaction.TX_SUBTYPE_TX,
                                  transaction.TX_SUBTYPE_COINBASE):
                continue
            if tx.txto == address or tx.txfrom == address:
                logger.info('%s found in transaction pool', address)

                tmp_txn = {
                    'subtype': tx.subtype,
                    'txhash': tx.txhash,
                    'block': 'unconfirmed',
                    'amount': tx.amount / 100000000.000000000,
                    'nonce': tx.nonce,
                    'ots_key': tx.ots_key,
                    'txto': tx.txto,
                    'txfrom': tx.txfrom,
                    'timestamp': 'unconfirmed'
                }

                if tx.subtype == transaction.TX_SUBTYPE_TX:
                    tmp_txn['fee'] = tx.fee / 100000000.000000000

                tmp_transactions.append(tmp_txn)
                txnhash_added.add(tx.txhash)

        addr['transactions'] = tmp_transactions

        my_txn = []
        try:
            my_txn = self.state.db.get('txn_' + address)
        except:
            pass

        for txn_hash in my_txn:
            txn_metadata = self.state.db.get(txn_hash)
            dict_txn_metadata = json.loads(txn_metadata[0])
            if dict_txn_metadata['subtype'] == transaction.TX_SUBTYPE_TX:
                tx = SimpleTransaction().json_to_transaction(txn_metadata[0])
            elif dict_txn_metadata[
                    'subtype'] == transaction.TX_SUBTYPE_COINBASE:
                tx = CoinBase().json_to_transaction(txn_metadata[0])

            if (tx.txto == address or tx.txfrom
                    == address) and tx.txhash not in txnhash_added:
                logger.info('%s found in block %s', address,
                            str(txn_metadata[1]))

                tmp_txn = {
                    'subtype': tx.subtype,
                    'txhash': tx.txhash,
                    'block': txn_metadata[1],
                    'timestamp': txn_metadata[2],
                    'amount': tx.amount / 100000000.000000000,
                    'nonce': tx.nonce,
                    'ots_key': tx.ots_key,
                    'txto': tx.txto,
                    'txfrom': tx.txfrom
                }

                if tx.subtype == transaction.TX_SUBTYPE_TX:
                    tmp_txn['fee'] = tx.fee / 100000000.000000000

                addr['transactions'].append(tmp_txn)
                txnhash_added.add(tx.txhash)

        if len(addr['transactions']) > 0:
            addr['state']['transactions'] = len(addr['transactions'])

        if addr == {'transactions': {}}:
            addr = {
                'status': 'error',
                'error': 'address not found',
                'method': 'address',
                'parameter': address
            }
        else:
            addr['status'] = 'ok'

        return json_print_telnet(addr)
Beispiel #24
0
    def exp_win(data=None):
        # TODO: incomplete

        ew = {'status': 'ok', 'expected_winner': {}}

        return json_print_telnet(ew)
Beispiel #25
0
    def parse_cmd(self, data):

        # Get entered line as an array of strings delimited by "space."
        # Will chomp away any extra spaces
        data = data.split()
        # Arguments include anything beyond the first index

        if len(data) != 0:  # if anything was entered

            command = data[0]
            args = None
            if len(data) > 0:  # args optional
                args = data[1:]

            if command.decode('utf-8') in self.cmd_list:

                # Use switch cases when porting to a different language
                if command == b'create':
                    self.factory.p2pFactory.pos.create_next_block(int(args[0]))
                    self.output['status'] = 0
                    self.output['message'].write('Creating blocknumber #' +
                                                 str(args[0]))
                elif command == b'getnewaddress':
                    self.getnewaddress(args)

                elif command == b'hexseed':
                    for addr_bundle in self.factory.chain.wallet.address_bundle:
                        if isinstance(addr_bundle.xmss, XMSS):
                            self.output['status'] = 0
                            self.output['message'].write(
                                'Address: ' + addr_bundle.xmss.get_address() +
                                '\r\n')
                            self.output['message'].write(
                                'Recovery seed: ' +
                                addr_bundle.xmss.get_hexseed() + '\r\n')
                            self.output['keys'] += ['Address', 'Recovery seed']
                            self.output[
                                'Address'] = addr_bundle.xmss.get_address()
                            self.output[
                                'Recovery seed'] = addr_bundle.xmss.get_hexseed(
                                )

                elif command == b'seed':
                    for addr_bundle in self.factory.chain.wallet.address_bundle:
                        if isinstance(addr_bundle.xmss, XMSS):
                            self.output['status'] = 0
                            self.output['message'].write(
                                'Address: ' + addr_bundle.xmss.get_address() +
                                '\r\n')
                            self.output['message'].write(
                                'Recovery seed: ' +
                                addr_bundle.xmss.get_mnemonic() + '\r\n')
                            self.output['keys'] += ['Address', 'Recovery seed']

                elif command == b'search':
                    if not args:
                        self.output['status'] = 1
                        self.output['message'].write(
                            '>>> Usage: search <txhash or Q-address>\r\n')
                        return

                    tmp_output = None
                    if args[0][0] == 'Q':
                        tmp_output = json.loads(
                            self.factory.chain.search_address(args[0]))
                        self.output['message'].write('Address: ' +
                                                     str(args[0]))
                        self.output['message'].write(
                            '\r\nBalance: ' +
                            str(tmp_output['state']['balance']))
                        self.output['message'].write(
                            '\r\nTransactions: ' +
                            str(tmp_output['state']['transactions']))
                        for tx in tmp_output['transactions']:
                            self.output['message'].write(str(tx['txhash']))
                            self.output['message'].write(' ')
                            self.output['message'].write(str(tx['txfrom']))
                            self.output['message'].write(' ')
                            self.output['message'].write(str(tx['txto']))
                            self.output['message'].write(' ')
                            self.output['message'].write(str(tx['amount']))
                            self.output['message'].write('\r\n')
                    else:
                        tmp_output = json.loads(
                            self.factory.chain.search_txhash(args[0]))
                        self.output['message'].write('Txnhash: ')
                        self.output['message'].write(args[0])
                        if tmp_output['status'] == 'Error':
                            self.output['message'].write('\r\n')
                            self.output['message'].write(
                                str(tmp_output['error']))
                            self.output['message'].write('\r\n')
                            return True
                        self.output['message'].write('\r\nTimestamp: ')
                        self.output['message'].write(tmp_output['timestamp'])
                        self.output['message'].write('\r\nBlockNumber: ')
                        self.output['message'].write(tmp_output['block'])
                        self.output['message'].write('\r\nConfirmations: ')
                        self.output['message'].write(
                            tmp_output['confirmations'])
                        self.output['message'].write('\r\nAmount: ')
                        self.output['message'].write(tmp_output['amount'])
                        self.output['message'].write('\r\n')

                    if not tmp_output:
                        self.output['status'] = 1
                        self.output['message'].write(
                            '>>> No Information available')
                        return True

                    for key in list(tmp_output.keys()):
                        self.output['keys'] += [str(key)]
                        self.output[key] = tmp_output[key]

                    self.output['status'] = 0
                    self.output['message'].write('')

                elif command == b'json_block':

                    if not args:
                        self.output['message'].write(
                            helper.json_print_telnet(
                                self.factory.chain.m_get_last_block()) +
                            '\r\n')
                        return True
                    try:
                        int(args[0])
                    except:
                        self.output['message'].write(
                            '>>> Try "json_block <block number>" \r\n')
                        return True

                    if int(args[0]) > self.factory.chain.m_blockheight():
                        self.output['message'].write(
                            '>>> Block > Blockheight\r\n')
                        return True
                    self.output['status'] = 0
                    self.output['message'].write(
                        helper.json_print_telnet(
                            self.factory.chain.m_get_block(int(args[0]))) +
                        '\r\n')

                elif command == b'savenewaddress':
                    self.savenewaddress()

                elif command == b'recoverfromhexseed':
                    if not args or not hexseed_to_seed(args[0]):
                        self.output['message'].write(
                            '>>> Usage: recoverfromhexseed <paste in hexseed>\r\n'
                        )
                        self.output['message'].write(
                            '>>> Could take up to a minute..\r\n')
                        self.output['message'].write(
                            '>>> savenewaddress if Qaddress matches expectations..\r\n'
                        )
                        return True

                    self.output['status'] = 0
                    addr = self.factory.chain.wallet.get_new_address(
                        address_type='XMSS', seed=hexseed_to_seed(args[0]))
                    self.factory.newaddress = addr
                    self.output['message'].write('>>> Recovery address: ' +
                                                 addr[1].get_address() +
                                                 '\r\n')
                    self.output['message'].write('>>> Recovery seed phrase: ' +
                                                 addr[1].get_mnemonic() +
                                                 '\r\n')
                    self.output['message'].write('>>> hexSEED confirm: ' +
                                                 addr[1].get_hexseed() +
                                                 '\r\n')
                    self.output['message'].write(
                        '>>> savenewaddress if Qaddress matches expectations..\r\n'
                    )

                    self.output['keys'] += [
                        'recovery_address', 'recovery_seed_phrase',
                        'hexseed_confirm'
                    ]
                    self.output['recovery_address'] = addr[1].get_address()
                    self.output['recovery_seed_phrase'] = addr[1].get_mnemonic(
                    )
                    self.output['hexseed_confirm'] = addr[1].get_hexseed()

                elif command == b'recoverfromwords':
                    if not args:
                        self.output['message'].write(
                            '>>> Usage: recoverfromwords <paste in 32 mnemonic words>\r\n'
                        )
                        return True
                    self.output['message'].write(
                        '>>> trying..this could take up to a minute..\r\n')
                    if len(args) != 32:
                        self.output['message'].write(
                            '>>> Usage: recoverfromwords <paste in 32 mnemonic words>\r\n'
                        )
                        return True

                    args = ' '.join(args)
                    addr = self.factory.chain.wallet.get_new_address(
                        address_type='XMSS', seed=mnemonic2bin(args, wordlist))
                    self.factory.newaddress = addr
                    self.output['status'] = 0
                    self.output['message'].write('>>> Recovery address: ' +
                                                 addr[1].get_address() +
                                                 '\r\n')
                    self.output['message'].write('>>> Recovery hexSEED: ' +
                                                 addr[1].get_hexseed() +
                                                 '\r\n')
                    self.output['message'].write('>>> Mnemonic confirm: ' +
                                                 addr[1].get_mnemonic() +
                                                 '\r\n')
                    self.output['message'].write(
                        '>>> savenewaddress if Qaddress matches expectations..\r\n'
                    )

                    self.output['keys'] += [
                        'recovery_address', 'recovery_hexseed',
                        'mnemonic_confirm'
                    ]
                    self.output['recovery_address'] = addr[1].get_address()
                    self.output['recovery_hexseed'] = addr[1].get_hexseed()
                    self.output['mnemonic_confirm'] = addr[1].get_mnemonic()

                elif command == b'stake':
                    self.output['status'] = 0
                    self.output['message'].write(
                        '>> Toggling stake from: ' +
                        str(self.factory.p2pFactory.stake) + ' to: ' +
                        str(not self.factory.p2pFactory.stake) + '\r\n')

                    self.factory.p2pFactory.stake = not self.factory.p2pFactory.stake
                    logger.info(
                        ('STAKING set to: ', self.factory.p2pFactory.stake))
                    self.output['keys'] += ['stake']
                    self.output['stake'] = self.factory.p2pFactory.stake

                elif command == b'stakenextepoch':
                    self.output['status'] = 0
                    self.output['message'].write(
                        '>>> Sending a stake transaction for address: ' +
                        self.factory.chain.mining_address +
                        ' to activate next epoch(' +
                        str(config.dev.blocks_per_epoch -
                            (self.factory.chain.m_blockchain[-1].blockheader.
                             blocknumber -
                             (self.factory.chain.m_blockchain[-1].blockheader.
                              epoch * config.dev.blocks_per_epoch))) +
                        ' blocks time)\r\n')

                    logger.info(('STAKE for address:',
                                 self.factory.chain.mining_address))

                    blocknumber = self.factory.chain.block_chain_buffer.height(
                    ) + 1
                    self.factory.p2pFactory.pos.make_st_tx(
                        blocknumber=blocknumber, first_hash=None)

                elif command == b'send':
                    self.send_tx(args)

                elif command == b'mempool':
                    self.output['status'] = 0
                    self.output['message'].write(
                        '>>> Number of transactions in memory pool: ' +
                        str(len(self.factory.chain.transaction_pool)) + '\r\n')
                    self.output['keys'] += ['txn_nos']
                    self.output['txn_nos'] = len(
                        self.factory.chain.transaction_pool)

                elif command == b'help':
                    self.output['status'] = 0
                    self.output['message'].write(
                        '>>> QRL ledger help: try {}'.format(', '.join(
                            self.cmd_list)) + '\r\n')
                # removed 'hrs, hrs_check,'
                elif command == b'quit' or command == b'exit':
                    self.transport.loseConnection()

                elif command == b'listaddresses':
                    addresses, num_sigs, types = self.factory.chain.wallet.inspect_wallet(
                    )
                    self.output['status'] = 0
                    self.output['keys'] += ['addresses']
                    self.output['addresses'] = []
                    for addr_bundle in range(len(addresses)):
                        self.output['message'].write(
                            str(addr_bundle) + ', ' + addresses[addr_bundle] +
                            '\r\n')
                        self.output['addresses'] += [addresses[addr_bundle]]

                elif command == b'wallet':
                    self.wallet()

                elif command == b'getinfo':
                    self.output['status'] = 0
                    self.output['message'].write(
                        '>>> Version: ' + self.factory.chain.version_number +
                        '\r\n')
                    self.output['message'].write('>>> Uptime: ' +
                                                 str(time.time() -
                                                     self.factory.start_time) +
                                                 '\r\n')
                    self.output['message'].write(
                        '>>> Nodes connected: ' +
                        str(len(self.factory.p2pFactory.peer_connections)) +
                        '\r\n')
                    self.output['message'].write(
                        '>>> Staking set to: ' +
                        str(self.factory.p2pFactory.stake) + '\r\n')
                    self.output['message'].write(
                        '>>> Sync status: ' +
                        self.factory.p2pFactory.nodeState.state.name + '\r\n')

                    self.output['keys'] += [
                        'version', 'uptime', 'nodes_connected',
                        'staking_status', 'sync_status'
                    ]
                    self.output['version'] = self.factory.chain.version_number
                    self.output['uptime'] = str(time.time() -
                                                self.factory.start_time)
                    self.output['nodes_connected'] = str(
                        len(self.factory.p2pFactory.peer_connections))
                    self.output['staking_status'] = str(
                        self.factory.p2pFactory.stake)
                    self.output[
                        'sync_status'] = self.factory.p2pFactory.nodeState.state.name

                elif command == b'blockheight':
                    self.output['status'] = 0
                    self.output['message'].write(
                        '>>> Blockheight: ' +
                        str(self.factory.chain.m_blockheight()) + '\r\n')
                    self.output['message'].write(
                        '>>> Headerhash: ' +
                        bin2hstr(self.factory.chain.m_blockchain[-1].
                                 blockheader.headerhash) + '\r\n')

                    self.output['keys'] += ['blockheight', 'headerhash']
                    self.output[
                        'blockheight'] = self.factory.chain.m_blockheight()
                    self.output['headerhash'] = bin2hstr(
                        self.factory.chain.m_blockchain[-1].blockheader.
                        headerhash)

                elif command == b'peers':
                    self.output['status'] = 0
                    self.output['message'].write('>>> Connected Peers:\r\n')
                    self.output['keys'] += ['peers']
                    self.output['peers'] = {}
                    for peer in self.factory.p2pFactory.peer_connections:
                        self.output['message'].write('>>> ' +
                                                     peer.conn_identity +
                                                     " [" + peer.version +
                                                     "]  blockheight: " +
                                                     str(peer.blockheight) +
                                                     '\r\n')
                        self.output['peers'][peer.conn_identity] = {}
                        self.output['peers'][
                            peer.conn_identity]['version'] = peer.version
                        self.output['peers'][peer.conn_identity][
                            'blockheight'] = peer.blockheight

                elif command == b'reboot':
                    if len(args) < 1:
                        self.output['message'].write(
                            '>>> reboot <password>\r\n')
                        self.output['message'].write('>>> or\r\n')
                        self.output['message'].write(
                            '>>> reboot <password> <nonce>\r\n')
                        self.output['message'].write('>>> or\r\n')
                        self.output['message'].write(
                            '>>> reboot <password> <nonce> <trim_blocknum>\r\n'
                        )
                        return True
                    json_hash, err = None, None
                    if len(args) == 3:
                        json_hash, status = self.factory.chain.generate_reboot_hash(
                            args[0], args[1], args[2])
                        self.output['message'].write(
                            str(args[0]) + str(args[1]) + str(args[2]))
                    elif len(args) == 2:
                        json_hash, status = self.factory.chain.generate_reboot_hash(
                            args[0], args[1])
                    else:
                        json_hash, status = self.factory.chain.generate_reboot_hash(
                            args[0])

                    if json_hash:
                        self.factory.p2pFactory.send_reboot(json_hash)
                        # self.factory.state.update(NState.synced)
                    self.output['message'].write(status)

        else:
            return False

        return True
Beispiel #26
0
    def _search_address(self, address):

        addr = {'transactions': []}

        txnhash_added = set()

        # FIXME: breaking encapsulation and accessing DB/cache directly from API
        if not self.factory.state.state_address_used(address):
            addr['status'] = 'error'
            addr['error'] = 'Address not found'
            addr['parameter'] = address
            return json_print_telnet(addr)

        # FIXME: This is a duplicate of balance
        # FIXME: breaking encapsulation and accessing DB/cache directly from API
        nonce, balance, pubhash_list = self.factory.state.state_get_address(
            address)
        addr['state'] = {}
        addr['state']['address'] = address
        addr['state']['balance'] = self._format_qrlamount(balance)
        addr['state']['nonce'] = nonce

        for s in self.factory.state.stake_list_get():
            if address == s[0]:
                addr['stake'] = {}
                addr['stake']['selector'] = s[2]
                # pubhashes used could be put here..

        tmp_transactions = []
        for tx in self.factory.chain.transaction_pool:
            if tx.subtype not in (TX_SUBTYPE_TX, TX_SUBTYPE_COINBASE):
                continue
            if tx.txto == address or tx.txfrom == address:
                logger.info('%s found in transaction pool', address)

                tmp_txn = {
                    'subtype': tx.subtype,
                    'txhash': bin2hstr(tx.txhash),
                    'block': 'unconfirmed',
                    'amount': self._format_qrlamount(tx.amount),
                    'nonce': tx.nonce,
                    'ots_key': tx.ots_key,
                    'txto': tx.txto,
                    'txfrom': tx.txfrom,
                    'timestamp': 'unconfirmed'
                }

                if tx.subtype == TX_SUBTYPE_TX:
                    tmp_txn['fee'] = self._format_qrlamount(tx.fee)

                tmp_txn.subtype = Transaction.tx_id_to_name(tx.subtype)

                tmp_transactions.append(tmp_txn)
                txnhash_added.add(tx.txhash)

        addr['transactions'] = tmp_transactions

        my_txn = []
        try:
            my_txn = self.factory.state.db.get('txn_' + address)
        except:
            pass

        for txn_hash in my_txn:
            txn_metadata = self.factory.state.db.get(txn_hash)
            dict_txn_metadata = json.loads(txn_metadata[0])
            if dict_txn_metadata['subtype'] == TX_SUBTYPE_TX:
                tx = SimpleTransaction().json_to_transaction(txn_metadata[0])
            elif dict_txn_metadata['subtype'] == TX_SUBTYPE_COINBASE:
                tx = CoinBase().json_to_transaction(txn_metadata[0])

            if (tx.txto == address or tx.txfrom
                    == address) and tx.txhash not in txnhash_added:
                logger.info('%s found in block %s', address,
                            str(txn_metadata[1]))

                tmp_txn = {
                    'subtype': tx.subtype,
                    'txhash': bin2hstr(tx.txhash),
                    'block': txn_metadata[1],
                    'timestamp': txn_metadata[2],
                    'amount': self._format_qrlamount(tx.amount),
                    'nonce': tx.nonce,
                    'ots_key': tx.ots_key,
                    'txto': tx.txto,
                    'txfrom': tx.txfrom
                }

                if tx.subtype == TX_SUBTYPE_TX:
                    tmp_txn['fee'] = self._format_qrlamount(tx.fee)

                tmp_txn['subtype'] = Transaction.tx_id_to_name(
                    tmp_txn['subtype'])

                addr['transactions'].append(tmp_txn)
                txnhash_added.add(tx.txhash)

        if len(addr['transactions']) > 0:
            addr['state']['transactions'] = len(addr['transactions'])

        if addr == {'transactions': {}}:
            addr = {
                'status': 'error',
                'error': 'address not found',
                'method': 'address',
                'parameter': address
            }
        else:
            addr['status'] = 'ok'

        return json_print_telnet(addr)
Beispiel #27
0
    def stats(self, data=None):
        logger.info('<<< API stats call')

        # calculate staked/emission %
        b = 0
        for staker in self.factory.state.stake_validators_list.sv_list:
            b += self.factory.state.state_balance(staker)
        staked = decimal.Decimal(
            (b / 100000000.000000000) /
            (self.factory.state.total_coin_supply() / 100000000.000000000) *
            100).quantize(decimal.Decimal('1.00'))  # /100000000.000000000)
        staked = float(str(staked))

        # calculate average blocktime over last 100 blocks..
        z = 0
        t = []

        last_n_block = 100

        last_block = self.factory.chain.m_blockchain[-1]
        for _ in range(last_n_block):
            if last_block.blockheader.blocknumber <= 0:
                break
            prev_block = self.factory.chain.m_get_block(
                last_block.blockheader.blocknumber - 1)
            x = last_block.blockheader.timestamp - prev_block.blockheader.timestamp
            last_block = prev_block
            t.append(x)
            z += x

        block_one = self.factory.chain.m_get_block(1)
        network_uptime = 0
        if block_one:
            network_uptime = time.time() - block_one.blockheader.timestamp

        block_time = 0
        block_time_variance = 0
        if len(t) > 0:
            block_time = z / len(t)
            block_time_variance = max(t) - min(
                t)  # FIXME: This is not the variance!

        net_stats = {
            'status':
            'ok',
            'version':
            self.factory.chain.version_number,
            'block_reward':
            self._format_qrlamount(
                self.factory.chain.m_blockchain[-1].blockheader.block_reward),
            'stake_validators':
            len(self.factory.chain.state.stake_validators_list.sv_list),
            'epoch':
            self.factory.chain.m_blockchain[-1].blockheader.epoch,
            'staked_percentage_emission':
            staked,
            'network':
            'qrl testnet',
            'network_uptime':
            network_uptime,
            'block_time':
            block_time,
            'block_time_variance':
            block_time_variance,
            'blockheight':
            self.factory.chain.m_blockheight(),
            'nodes':
            len(self.factory.peers) + 1,
            'emission':
            self._format_qrlamount(self.factory.state.total_coin_supply()),
            'unmined':
            config.dev.total_coin_supply -
            self.factory.state.total_coin_supply() / 100000000.000000000
        }

        return json_print_telnet(net_stats)