def __str__(self): return "'{}' with {} addressed from {} to {}".format( self.token_id, self.value(), util.bytes2string(self.prev_address or '') or '<own balance>', util.bytes2string(self.address or '') or '<own balance>', )
def add_component(self, component_bytestring): """ We got a new StateComponent. """ # Deserialize it component = self.state_component_class(component_bytestring) # Get its hash component_hash = component.get_hash() if component_hash in self.queued_set: # We asked for this one, and now we have it self.queued_set.remove(component_hash) # Save it self.downloaded_components[component_hash] = component logging.debug("Accepted StateComponent {}".format( util.bytes2string(component_hash))) elif component_hash in self.downloaded_components: # We don't need that one because we have it already. logging.debug("StateComponent {} was already downloaded.".format( util.bytes2string(component_hash))) else: # We got someting we didn't ask for. logging.warning("StateComponent {} was unsolicited!".format( util.bytes2string(component_hash)))
def __str__(self): """ """ lines = [] lines.append("---TokenProfile {}---".format(self.token_id)) lines.append("{} records".format(len(self.records))) for i, record in enumerate(self.records): lines.append("\t{}: {}".format(i, str(record))) lines.append('Owner: {}'.format(util.bytes2string(self.owner().address))) lines.append('Creator: {}'.format(util.bytes2string(self.creator().address))) return "\n".join(lines)
def download(self, root_hash): """ Download the StateComponent tree for the given root hash. Re-sets any in-progress download and clears the set of requests. Keeps the downloaded StateCompinents and subtrees since they will probably be re- used at least partially. Call tick after this so that get_requests will have something in it. """ # Throw out the old requested component set self.queued_set = set() # Set the root hash self.root_hash = root_hash # Clear off the stack, since we need to come down from the new root and # download different branches. In the ideal case we'll have lots of # subtrees already from our local store or the parts we've been # downloading. self.stack = [] logging.info("Now downloading state {}".format( util.bytes2string(self.root_hash))) # Start a timer so we know when the state download is done. Don't # replace a running timer because we may switch to downloading a # different state in the middle. science.start_timer("state_download", replace=False)
def tick(self): """ Advance the stack until either we have some components to download or the stack empties and we have the root subtree and we're done with our download. """ if len(self.stack) == 0 and not self.have_subtree(self.root_hash): # We still need the root subtree if self.have_component(self.root_hash): # We got the root component, though. Put it on the stack so we # can go get its children. self.stack.append(self.get_component(self.root_hash)) else: # We need to download the root component first. self.queued_set.add(self.root_hash) logging.debug("Need to download root hash: {}".format( util.bytes2string(self.root_hash))) while len(self.stack) > 0 and self.process_stack(): # Keep going through this loop pass
def render_GET(self, request): global _BlockIndexByTimestamp src = ''' <head> <title>PyBC Node on %(hostname)s:%(hostinfo)s</title> <style>%(css)s</style> </head> <body>''' % dict( hostname=self.peer.external_address, hostinfo=self.peer.port, css=css_styles(dict( block_background='#f0f0f0', block_border='c0c0c0', transaction_background='#fdfdfd', transaction_border='#d0d0d0', input_background='#e0e0ff', input_border='#c0c0df', output_background='#e0ffe0', output_border='#c0dfc0', authorization_background='#ffe0e0', authorization_border='#dfc0c0', f_json_bg='#FAFAD2', f_json_border='#dfc0c0', )), ) src += '<div id="content">\n' src += '<h1>PyBC Node on {}:{}</h1>\n'.format(self.peer.external_address, self.peer.port) src += 'network name: {}<br>\n'.format(self.peer.network) src += 'software version: {}<br>\n'.format(self.peer.version) src += 'number of blocks: {}<br>\n'.format(len(self.peer.blockchain.blockstore)) src += 'local disk usage: {}<br>\n'.format(self.peer.blockchain.get_disk_usage()) src += '<h1>blocks:</h1>\n' for block in self.peer.blockchain.longest_chain(): src += '<div class="block panel-big">\n' src += '<div class="b_header panel-small">\n' src += '<b><code>{}</code></b> from <i>{}</i>,\n'.format( util.bytes2string(block.block_hash(), limit=8), time.ctime(block.timestamp)) src += 'previous hash: <b><code>{}</code></b>,\n'.format( util.bytes2string(block.previous_hash, limit=8)) src += 'state hash: <code>{}</code>,\n'.format( util.bytes2string(block.state_hash, limit=8)) src += 'body hash: <code>{}</code>,\n'.format( util.bytes2string(block.body_hash, limit=8)) src += 'nonce: {}, height: {}, payload size: {} bytes \n'.format( block.nonce, block.height, len(block.payload)) src += '</div>\n' # b_header src += '<div class="b_body panel-small">\n' if not block.has_body: src += 'EMPTY BODY\n' else: for transaction_bytes in transactions.unpack_transactions(block.payload): tr = json_coin.JsonTransaction.from_bytes(transaction_bytes) src += '<div class="transaction panel-medium">\n' src += '<div class="t_header panel-small">\n' src += '<b>transaction</b> from <i>{}</i>, hash: <b><code>{}</code></b>\n'.format( time.ctime(tr.timestamp), util.bytes2string(tr.transaction_hash(), limit=8)) src += '</div>\n' # t_header src += '<div class="t_body panel-small">\n' src += '<div class="t_inputs panel-medium">\n' if not tr.inputs: src += '<div class="t_input panel-small">\n' src += '<div class="field">no inputs</div>\n' src += '</div>\n' # t_input else: for inpt in tr.inputs: src += '<div class="t_input panel-small">\n' src += '<div class="field f_amount">{}</div>\n'.format(inpt[2]) src += '<div class="field f_destination"><b><code>{}</code></b></div>\n'.format( util.bytes2string(inpt[3], limit=8)) src += '<div class="field f_index">#{}</div>\n'.format(inpt[1]) src += '<div class="field f_hash"><code>{}</code></div>\n'.format( util.bytes2string(inpt[0], limit=8)) if inpt[4] is not None: src += '<div class="field f_json"><code>{}</code></div>\n'.format(inpt[4]) src += '</div>\n' # t_input src += '</div>\n' # t_inputs src += '<div class="t_outputs panel-medium">\n' if not tr.outputs: src += '<div class="t_output panel-small">\n' src += '<div class="field">no outputs</div>\n' src += '</div>\n' # t_output else: for outpt in tr.outputs: src += '<div class="t_output panel-small">\n' src += '<div class="field f_amount">{}</div>\n'.format(outpt[0]) src += '<div class="field f_destination"><b><code>{}</code></b></div>\n'.format( util.bytes2string(outpt[1], limit=8)) if outpt[2] is not None: src += '<div class="field f_json"><code>{}</code></div>\n'.format(outpt[2]) src += '</div>\n' # t_input src += '</div>\n' # t_outputs src += '<div class="t_authorizations panel-medium">\n' if not tr.authorizations: src += '<div class="t_authorization panel-small">\n' src += '<div class="field">no authorizations</div>\n' src += '</div>\n' # t_authorization else: for author in tr.authorizations: src += '<div class="t_authorization panel-small">\n' src += '<div class="field f_pub_key"><code>{}</code></div>\n'.format( util.bytes2string(author[0], limit=10)) src += '<div class="field f_signature"><code>{}</code></div>\n'.format( util.bytes2string(author[1], limit=10)) if author[2] is not None: src += '<div class="field f_json"><code>{}</code></div>\n'.format(author[2]) src += '</div>\n' # t_authorization src += '</div>\n' # t_authorizations src += '</div>\n' # t_body src += '</div>\n' # transaction src += '</div>\n' # b_body src += '</div>\n' # block src += '</div>\n' # content src += '</body>\n' src += '</html>' return src