def block_data( self, data=None ): # if no data = last block ([-1]) #change this to add error.. error = { 'status': 'error', 'error': 'block not found', 'method': 'block_data', 'parameter': data } printL(('<<< API block data call', data)) if not data: data = self.factory.chain.m_get_last_block() data1 = copy.deepcopy(data) data1.status = 'ok' return helper.json_print_telnet(data1) try: int(data) # is the data actually a number? except: return helper.json_print_telnet(error) js_bk = self.factory.chain.m_get_block(int(data)) if js_bk == False: return helper.json_print_telnet(error) else: js_bk1 = copy.deepcopy(js_bk) js_bk1.status = 'ok' js_bk1.blockheader.block_reward = js_bk1.blockheader.block_reward / 100000000.000000000 return helper.json_print_telnet(js_bk1)
def ping(self, data=None): printL(('<<< 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 = {} pings['status'] = 'ok' pings['peers'] = {} pings['peers'] = self.factory.chain.ping_list return helper.json_print_telnet(pings)
def empty(self, data=None): error = { 'status': 'error', 'error': 'no method supplied', 'methods available': 'block_data, stats, txhash, address, last_tx, \ last_block, richlist, ping, stake_commits, stake_reveals, stakers, \ next_stakers' } return helper.json_print_telnet(error)
def parse_cmd(self, data): data = data.split() args = data[1:] if len(data) != 0: if data[0] in self.cmd_list: if data[0] == 'getnewaddress': self.getnewaddress(args) return if data[0] == 'hexseed': for x in self.factory.chain.my: if type(x[1]) == list: pass else: if x[1].type == 'XMSS': self.transport.write('Address: ' + x[1].address + '\r\n') self.transport.write('Recovery seed: ' + x[1].hexSEED + '\r\n') return if data[0] == 'seed': for x in self.factory.chain.my: if type(x[1]) == list: pass else: if x[1].type == 'XMSS': self.transport.write('Address: ' + x[1].address + '\r\n') self.transport.write('Recovery seed: ' + x[1].mnemonic + '\r\n') return elif data[0] == 'search': if not args: self.transport.write( '>>> Usage: search <txhash or Q-address>' + '\r\n') return for result in self.factory.chain.search_telnet(args[0], long=0): self.transport.write(result + '\r\n') return elif data[0] == 'json_search': if not args: self.transport.write( '>>>Usage: search <txhash or Q-address>' + '\r\n') return for result in self.factory.chain.search_telnet(args[0], long=1): self.transport.write(result + '\r\n') return elif data[0] == 'json_block': if not args: # chain.json_printL(((chain.m_get_last_block()) self.transport.write( helper.json_print_telnet( self.factory.chain.m_get_last_block()) + '\r\n') return try: int(args[0]) except: self.transport.write( '>>> Try "json_block <block number>" ' + '\r\n') return if int(args[0]) > self.factory.chain.m_blockheight(): self.transport.write('>>> Block > Blockheight' + '\r\n') return self.transport.write( helper.json_print_telnet( self.factory.chain.m_get_block(int(args[0]))) + '\r\n') return elif data[0] == 'savenewaddress': self.savenewaddress() elif data[0] == 'recoverfromhexseed': if not args or not hexseed_to_seed(args[0]): self.transport.write( '>>> Usage: recoverfromhexseed <paste in hexseed>' + '\r\n') self.transport.write( '>>> Could take up to a minute..' + '\r\n') self.transport.write( '>>> savenewaddress if Qaddress matches expectations..' + '\r\n') return self.transport.write( '>>> trying.. this could take up to a minute..' + '\r\n') addr = self.factory.chain.wallet.getnewaddress( type='XMSS', SEED=hexseed_to_seed(args[0])) self.factory.newaddress = addr self.transport.write('>>> Recovery address: ' + addr[1].address + '\r\n') self.transport.write('>>> Recovery seed phrase: ' + addr[1].mnemonic + '\r\n') self.transport.write('>>> hexSEED confirm: ' + addr[1].hexSEED + '\r\n') self.transport.write( '>>> savenewaddress if Qaddress matches expectations..' + '\r\n') return elif data[0] == 'recoverfromwords': if not args: self.transport.write( '>>> Usage: recoverfromwords <paste in 32 mnemonic words>' + '\r\n') return self.transport.write( '>>> trying..this could take up to a minute..' + '\r\n') if len(args) != 32: self.transport.write( '>>> Usage: recoverfromwords <paste in 32 mnemonic words>' + '\r\n') return args = ' '.join(args) addr = self.factory.chain.wallet.getnewaddress( type='XMSS', SEED=mnemonic_to_seed(args)) self.factory.newaddress = addr self.transport.write('>>> Recovery address: ' + addr[1].address + '\r\n') self.transport.write('>>> Recovery hexSEED: ' + addr[1].hexSEED + '\r\n') self.transport.write('>>> Mnemonic confirm: ' + addr[1].mnemonic + '\r\n') self.transport.write( '>>> savenewaddress if Qaddress matches expectations..' + '\r\n') return elif data[0] == 'stake': self.transport.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 printL(('STAKING set to: ', self.factory.p2pFactory.stake)) return elif data[0] == 'stakenextepoch': self.transport.write( '>>> Sending a stake transaction for address: ' + self.factory.chain.mining_address + ' to activate next epoch(' + str(c.blocks_per_epoch - (self.factory.chain.m_blockchain[-1].blockheader. blocknumber - (self.factory.chain.m_blockchain[-1].blockheader. epoch * c.blocks_per_epoch))) + ' blocks time)' + '\r\n') printL(('STAKE for address:', self.factory.chain.mining_address)) self.factory.p2pFactory.send_st_to_peers( StakeTransaction().create_stake_transaction( self.factory.chain.mining_address, self.factory.chain.block_chain_buffer.height() + 1, self.factory.chain.my[0][1], balance=self.factory.chain.state.state_balance( self.factory.chain.mining_address))) return elif data[0] == 'send': self.send_tx(args) elif data[0] == 'mempool': self.transport.write( '>>> Number of transactions in memory pool: ' + str(len(self.factory.chain.transaction_pool)) + '\r\n') elif data[0] == 'help': self.transport.write( '>>> QRL ledger help: try quit, wallet, send, getnewaddress, search, recoverfromhexseed, recoverfromwords, stake, stakenextepoch, mempool, json_block, json_search, seed, hexseed, getinfo, peers, or blockheight' + '\r\n') # removed 'hrs, hrs_check,' elif data[0] == 'quit' or data[0] == 'exit': self.transport.loseConnection() elif data[0] == 'listaddresses': addresses, num_sigs, types = self.factory.chain.wallet.inspect_wallet( ) for x in range(len(addresses)): self.transport.write( str(x) + ', ' + addresses[x] + '\r\n') elif data[0] == 'wallet': self.wallet() elif data[0] == 'getinfo': self.transport.write('>>> Version: ' + self.factory.chain.version_number + '\r\n') self.transport.write('>>> Uptime: ' + str(time.time() - self.factory.start_time) + '\r\n') self.transport.write( '>>> Nodes connected: ' + str(len(self.factory.p2pFactory.peers)) + '\r\n') self.transport.write('>>> Staking set to: ' + str(self.factory.p2pFactory.stake) + '\r\n') self.transport.write( '>>> Sync status: ' + self.factory.p2pFactory.nodeState.state + '\r\n') elif data[0] == 'blockheight': self.transport.write( '>>> Blockheight: ' + str(self.factory.chain.m_blockheight()) + '\r\n') self.transport.write('>>> Headerhash: ' + self.factory.chain.m_blockchain[-1]. blockheader.headerhash + '\r\n') elif data[0] == 'peers': self.transport.write('>>> Connected Peers:\r\n') for peer in self.factory.p2pFactory.peers: self.transport.write('>>> ' + peer.identity + " [" + peer.version + "] blockheight: " + str(peer.blockheight) + '\r\n') elif data[0] == 'reboot': if len(args) < 1: self.transport.write('>>> reboot <password>\r\n') self.transport.write('>>> or\r\n') self.transport.write( '>>> reboot <password> <nonce>\r\n') self.transport.write('>>> or\r\n') self.transport.write( '>>> reboot <password> <nonce> <trim_blocknum>\r\n' ) return 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.transport.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('synced') self.transport.write(status) else: return False return True
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] != 'GET' and data[0] != 'OPTIONS': return False if data[0] == '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][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(helper.json_print_telnet(error)) return False #my_cls = ApiProtocol() # call the command from api_list directly api_call = getattr(self, data[1].lower()) if len(data) < 3: json_txt = api_call() # self.transport.write(api_call()) else: json_txt = api_call(data[2]) # self.transport.write(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(http_header_GET + json_txt) return
def stats(self, data=None): printL(('<<< API stats call')) # calculate staked/emission % b = 0 for s in self.factory.state.stake_list_get(): b += self.factory.state.state_balance(s[0]) staked = decimal.Decimal( (b / 100000000.000000000) / (self.factory.state.db.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 net_stats = { 'status': 'ok', 'version': self.factory.chain.version_number, 'block_reward': self.factory.chain.m_blockchain[-1].blockheader.block_reward / 100000000.00000000, 'stake_validators': len(self.factory.chain.m_blockchain[-1].blockheader.reveal_list), 'epoch': self.factory.chain.m_blockchain[-1].blockheader.epoch, 'staked_percentage_emission': staked, 'network': 'qrl testnet', 'network_uptime': time.time() - self.factory.chain.m_blockchain[1].blockheader.timestamp, 'block_time': z / len(t), 'block_time_variance': max(t) - min(t), 'blockheight': self.factory.chain.m_blockheight(), 'nodes': len(self.factory.peers) + 1, 'emission': self.factory.state.db.total_coin_supply() / 100000000.000000000, 'unmined': 21000000 - self.factory.state.db.total_coin_supply() / 100000000.000000000 } return helper.json_print_telnet(net_stats)
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 in self.cmd_list: # Use switch cases when porting to a different language if command == 'getnewaddress': self.getnewaddress(args) return if command == 'hexseed': for x in self.factory.chain.my: if type(x[1]) == list: pass else: if x[1].type == 'XMSS': self.output['status'] = 0 self.output['message'].write('Address: ' + x[1].address + '\r\n') self.output['message'].write('Recovery seed: ' + x[1].hexSEED + '\r\n') self.output['keys'] += ['Address','Recovery seed'] self.output['Address'] = x[1].address self.output['Recovery seed'] = x[1].hexSEED return if command == 'seed': for x in self.factory.chain.my: if type(x[1]) == list: pass else: if x[1].type == 'XMSS': self.output['status'] = 0 self.output['message'].write('Address: ' + x[1].address + '\r\n') self.output['message'].write('Recovery seed: ' + x[1].mnemonic + '\r\n') self.output['keys'] += ['Address', 'Recovery seed'] return elif command == '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])) else: tmp_output = json.loads(self.factory.chain.search_txhash(args[0])) if not tmp_output: self.output['status'] = 1 self.output['message'].write('>>> No Information available') return for key in tmp_output.keys(): self.output['keys'] += [key] self.output[key] = tmp_output[key] self.output['status'] = 0 self.output['message'].write('') return elif command == 'json_block': if not args: self.output['message'].write(helper.json_print_telnet(self.factory.chain.m_get_last_block()) + '\r\n') return try: int(args[0]) except: self.output['message'].write('>>> Try "json_block <block number>" ' + '\r\n') return if int(args[0]) > self.factory.chain.m_blockheight(): self.output['message'].write('>>> Block > Blockheight' + '\r\n') return self.output['status'] = 0 self.output['message'].write(helper.json_print_telnet(self.factory.chain.m_get_block(int(args[0]))) + '\r\n') return elif command == 'savenewaddress': self.savenewaddress() elif command == '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 self.output['status'] = 0 addr = self.factory.chain.wallet.getnewaddress(type='XMSS', SEED=hexseed_to_seed(args[0])) self.factory.newaddress = addr self.output['message'].write('>>> Recovery address: ' + addr[1].address + '\r\n') self.output['message'].write('>>> Recovery seed phrase: ' + addr[1].mnemonic + '\r\n') self.output['message'].write('>>> hexSEED confirm: ' + addr[1].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].address self.output['recovery_seed_phrase'] = addr[1].mnemonic self.output['hexseed_confirm'] = addr[1].hexSEED return elif command == 'recoverfromwords': if not args: self.output['message'].write('>>> Usage: recoverfromwords <paste in 32 mnemonic words>' + '\r\n') return 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 args = ' '.join(args) addr = self.factory.chain.wallet.getnewaddress(type='XMSS', SEED=mnemonic_to_seed(args)) self.factory.newaddress = addr self.output['status'] = 0 self.output['message'].write('>>> Recovery address: ' + addr[1].address + '\r\n') self.output['message'].write('>>> Recovery hexSEED: ' + addr[1].hexSEED + '\r\n') self.output['message'].write('>>> Mnemonic confirm: ' + addr[1].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].address self.output['recovery_hexseed'] = addr[1].hexSEED self.output['mnemonic_confirm'] = addr[1].mnemonic return elif command == '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 return elif command == '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)) self.factory.p2pFactory.send_st_to_peers( StakeTransaction().create_stake_transaction(self.factory.chain.mining_address, self.factory.chain.block_chain_buffer.height() + 1, self.factory.chain.my[0][1], balance=self.factory.chain.state.state_balance( self.factory.chain.mining_address))) return elif command == 'send': self.send_tx(args) elif command == '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 == 'help': self.output['status'] = 0 self.output['message'].write( '>>> QRL ledger help: try quit, wallet, send, getnewaddress, search, recoverfromhexseed, recoverfromwords, stake, stakenextepoch, mempool, json_block, json_search, seed, hexseed, getinfo, peers, or blockheight' + '\r\n') # removed 'hrs, hrs_check,' elif command == 'quit' or command == 'exit': self.transport.loseConnection() elif command == 'listaddresses': addresses, num_sigs, types = self.factory.chain.wallet.inspect_wallet() self.output['status'] = 0 self.output['keys'] += ['addresses'] self.output['addresses'] = [] for x in range(len(addresses)): self.output['message'].write(str(x) + ', ' + addresses[x] + '\r\n') self.output['addresses'] += [addresses[x]] elif command == 'wallet': self.wallet() elif command == '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.peers)) + '\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 + '\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.peers)) self.output['staking_status'] = str(self.factory.p2pFactory.stake) self.output['sync_status'] = self.factory.p2pFactory.nodeState.state elif command == 'blockheight': self.output['status'] = 0 self.output['message'].write('>>> Blockheight: ' + str(self.factory.chain.m_blockheight()) + '\r\n') self.output['message'].write( '>>> Headerhash: ' + 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'] = self.factory.chain.m_blockchain[-1].blockheader.headerhash elif command == '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.peers: self.output['message'].write('>>> ' + peer.identity + " [" + peer.version + "] blockheight: " + str( peer.blockheight) + '\r\n') self.output['peers'][peer.identity] = {} self.output['peers'][peer.identity]['version'] = peer.version self.output['peers'][peer.identity]['blockheight'] = peer.blockheight elif command == '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 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('synced') self.output['message'].write(status) else: return False return True