class Block(Message): command = "block" properties = [ ('version', format.FormatTypeNumber('I')), ('prev_block', format.FormatTypeBytes(32)), ('merkle_root', format.FormatTypeBytes(32)), ('timestamp', format.FormatTypeNumber('I', allow_float=True)), ('bits', format.FormatTypeNumber('I')), ('nonce', format.FormatTypeNumber('I')), ('txns', format.FormatTypeArray(format.FormatTypeTxn())), ] @staticmethod def from_block(block): return Block(block.version, block.previous_block_hash, block.merkle_root, block.timestamp, block.bits, block.nonce, block.transactions) def _debug(self): block_hash = util.get_block_header(self.version, self.prev_block, self.merkle_root, self.timestamp, self.bits, self.nonce) return _debug(self, [('h', block_hash.encode('hex')), ('t', self.txns)])
class FilterLoad(Message): command = "filterload" name = "filter_load" do_not_register = True properties = [ ('filter', format.FormatTypeArray(format.FormatTypeNumber('B'))), ('n_hashes_func', format.FormatTypeNumber('I')), ('n_tweak', format.FormatTypeNumber('I')), ('n_flags', format.FormatTypeNumber('B')), ]
class Transaction(Message): command = "tx" name = "transaction" properties = [ ('version', format.FormatTypeNumber('I')), ('tx_in', format.FormatTypeArray(format.FormatTypeTxnIn(), 1)), ('tx_out', format.FormatTypeArray(format.FormatTypeTxnOut(), 1)), ('lock_time', format.FormatTypeNumber('I')), ] def _debug(self): return _debug(self, [('in', self.tx_in), ('out', self.tx_out)])
class Reject(Message): command = "reject" properties = [ ('message', format.FormatTypeVarString()), ('ccode', format.FormatTypeNumber('B')), ('reason', format.FormatTypeVarString()), ] def _debug(self): return _debug(self, [('m', self.message), ('r', self.reason)])
class Version(Message): command = "version" properties = [ ('version', format.FormatTypeNumber('i')), ('services', format.FormatTypeNumber('Q')), ('timestamp', format.FormatTypeNumber('q', allow_float=True)), ('addr_recv', format.FormatTypeNetworkAddressWithoutTimestamp()), ('addr_from', format.FormatTypeNetworkAddressWithoutTimestamp()), ('nonce', format.FormatTypeBytes(8)), ('user_agent', format.FormatTypeVarString()), ('start_height', format.FormatTypeNumber('i')), ('relay', format.FormatTypeOptional(format.FormatTypeNumber('B'), True)), ] def _debug(self): return _debug(self, [ ('v', self.version), ('s', self.services), ('ua', self.user_agent), ('sh', self.start_height), ])
class GetBlocks(Message): command = "getblocks" name = "get_blocks" properties = [ ('version', format.FormatTypeNumber('I')), ('block_locator_hashes', format.FormatTypeArray(format.FormatTypeBytes(32), 1)), ('hash_stop', format.FormatTypeBytes(32)), ] def _debug(self): return _debug( self, [('blh', [h.encode('hex') for h in self.block_locator_hashes])])
class MerkleBlock(Message): command = "merkleblock" name = "merkle_block" do_not_register = True properties = [ ('version', format.FormatTypeNumber('I')), ('prev_block', format.FormatTypeBytes(32)), ('merkle_root', format.FormatTypeBytes(32)), ('timestamp', format.FormatTypeNumber('I', allow_float=True)), ('bits', format.FormatTypeNumber('I')), ('nonce', format.FormatTypeNumber('I')), ('total_transactions', format.FormatTypeNumber('I')), ('hashes', format.FormatTypeArray(format.FormatTypeBytes(32))), ('flags', format.FormatTypeArray(format.FormatTypeNumber('b'))), ]
def _parse_and_get(self, name): if not hasattr(self, '_data'): self._data = dict() if not self._data: data = self.payload self._data = dict() offset = 0 # extract version, relay_until, expiration, id and cancel (v, r, e, i, c) = struct.unpack('<iqqii', data[offset:offset + 28]) self._data['version'] = v self._data['relay_until'] = r self._data['expiration'] = e self._data['id'] = i self._data['cancel'] = c offset += 28 # extract the set of alerts this alert cancels (vl, s) = format.parse_variable_set(data[offset:], format.FormatTypeNumber('i')) self._data['set_cancel'] = s offset += vl # extract minimum and maximum versions affecte by this alert (minver, maxver) = struct.unpack('<ii', data[offset:offset + 8]) self._data['min_ver'] = minver self._data['max_ver'] = maxver offset += 8 # extract the set of sub-versions affected by this alert (vl, s) = format.parse_variable_set(data[offset:], format.FormatTypeVarString()) self._data['set_sub_ver'] = s offset += vl # extract priority (p, ) = struct.unpack('<i', data[offset:offset + 4]) self._data['priority'] = p offset += 4 # extract comment (no need to display) (vl, c) = format.FormatTypeVarString.parse(data[offset:]) self._data['comment'] = c offset += vl # extract status bar message (should be shown in the UI) (vl, s) = format.FormatTypeVarString.parse(data[offset:]) self._data['status_bar'] = s offset += vl # just incase *this* is an old version and the new format includes # extra stuff, we can still view it (vl, r) = format.FormatTypeVarString.parse(data[offset:]) self._data['reserved'] = r offset += vl return self._data[name]