예제 #1
0
 def create_ohlist_wrong_no_hashes(self,chunkid):
     index,begin,length = chunkid
     ohlist = [ (0,'#' * 20),(1,'$' * 20)]  # should contain 3 for file2.wmv: own, sibling and root
     bohlist = bencode(ohlist)
     chunk = '*' * (2 ** 14)
     payload = tobinary(index)+tobinary(begin)+tobinary(len(bohlist))+bohlist+chunk
     return EXTEND+HASHPIECE+payload
 def create_ohlist_not_bdecodable(self, chunkid):
     index, begin, length = chunkid
     bohlist = 'bla'
     chunk = '*' * (2**14)
     payload = tobinary(index) + tobinary(begin) + tobinary(
         len(bohlist)) + bohlist + chunk
     return EXTEND + HASHPIECE + payload
예제 #3
0
 def create_bad_chunk(self,chunkid):
     index,begin,length = chunkid
     ohlist = self.tree.get_hashes_for_piece(index)
     bohlist = bencode(ohlist)
     chunk = '*' * length
     payload = tobinary(index)+tobinary(begin)+tobinary(len(bohlist))+bohlist+chunk
     return EXTEND+HASHPIECE+payload
예제 #4
0
 def send_g2g_piece_xfer_v1(self, index, begin, piece):
     """ Send fact that we sent piece index[begin:begin+chunk] to a peer
     to all peers (G2G V1).
     """
     self._send_message(
         self.his_extend_msg_name_to_id(EXTEND_MSG_G2G_V1) +
         tobinary(index) + tobinary(begin) + tobinary(len(piece)))
예제 #5
0
 def create_not_hashpiece(self,chunkid):
     index,begin,length = chunkid
     ohlist = []
     bohlist = bencode(ohlist)
     chunk = self.read_chunk(index,begin,length)
     payload = tobinary(index)+tobinary(begin)+tobinary(len(bohlist))+bohlist+chunk
     return EXTEND+chr(231)+payload
 def create_bad_chunk(self, chunkid):
     index, begin, length = chunkid
     ohlist = self.tree.get_hashes_for_piece(index)
     bohlist = bencode(ohlist)
     chunk = '*' * length
     payload = tobinary(index) + tobinary(begin) + tobinary(
         len(bohlist)) + bohlist + chunk
     return EXTEND + HASHPIECE + payload
예제 #7
0
 def create_ohlist_wrong_bad_hash(self,chunkid):
     index,begin,length = chunkid
     ohlist = self.tree.get_hashes_for_piece(index)
     ohlist[1][1] = '$' * 20
     bohlist = bencode(ohlist)
     chunk = self.read_chunk(index,begin,length)
     payload = tobinary(index)+tobinary(begin)+tobinary(len(bohlist))+bohlist+chunk
     return EXTEND+HASHPIECE+payload
 def create_not_hashpiece(self, chunkid):
     index, begin, length = chunkid
     ohlist = []
     bohlist = bencode(ohlist)
     chunk = self.read_chunk(index, begin, length)
     payload = tobinary(index) + tobinary(begin) + tobinary(
         len(bohlist)) + bohlist + chunk
     return EXTEND + chr(231) + payload
 def create_ohlist_wrong_no_hashes(self, chunkid):
     index, begin, length = chunkid
     ohlist = [(0, '#' * 20), (1, '$' * 20)
               ]  # should contain 3 for file2.wmv: own, sibling and root
     bohlist = bencode(ohlist)
     chunk = '*' * (2**14)
     payload = tobinary(index) + tobinary(begin) + tobinary(
         len(bohlist)) + bohlist + chunk
     return EXTEND + HASHPIECE + payload
 def create_ohlist_wrong_bad_hash(self, chunkid):
     index, begin, length = chunkid
     ohlist = self.tree.get_hashes_for_piece(index)
     ohlist[1][1] = '$' * 20
     bohlist = bencode(ohlist)
     chunk = self.read_chunk(index, begin, length)
     payload = tobinary(index) + tobinary(begin) + tobinary(
         len(bohlist)) + bohlist + chunk
     return EXTEND + HASHPIECE + payload
예제 #11
0
    def send_request(self, index, begin, length):
        global helping 
        global helpedlowpeers

        x.update("REQCOUNT", float(x.data["REQCOUNT"][0]) + 1)
        if helping and self.get_ip() in helpedlowpeers:
            return
        self._send_message(REQUEST + tobinary(index) + 
            tobinary(begin) + tobinary(length))
        if DEBUG_NORMAL_MSGS:
            print >>sys.stderr,"sending REQUEST to",self.get_ip()
            print >>sys.stderr,'sent request: '+str(index)+': '+str(begin)+'-'+str(begin+length)
예제 #12
0
 def create_ohlist_wrong_no_root_hash(self,chunkid):
     index,begin,length = chunkid
     ohlist = self.tree.get_hashes_for_piece(index)
     newohlist = []
     # Remove root hash
     for oh in ohlist:
         if oh[0] != 0:
             newohlist.append(oh)
     ohlist = newohlist
     bohlist = bencode(ohlist)
     chunk = self.read_chunk(index,begin,length)
     payload = tobinary(index)+tobinary(begin)+tobinary(len(bohlist))+bohlist+chunk
     return EXTEND+HASHPIECE+payload
예제 #13
0
    def send_request(self, index, begin, length):
        global helping
        global helpedlowpeers

        x.update("REQCOUNT", float(x.data["REQCOUNT"][0]) + 1)
        if helping and self.get_ip() in helpedlowpeers:
            return
        self._send_message(REQUEST + tobinary(index) + tobinary(begin) +
                           tobinary(length))
        if DEBUG_NORMAL_MSGS:
            print >> sys.stderr, "sending REQUEST to", self.get_ip()
            print >> sys.stderr, 'sent request: ' + str(index) + ': ' + str(
                begin) + '-' + str(begin + length)
 def create_ohlist_wrong_no_root_hash(self, chunkid):
     index, begin, length = chunkid
     ohlist = self.tree.get_hashes_for_piece(index)
     newohlist = []
     # Remove root hash
     for oh in ohlist:
         if oh[0] != 0:
             newohlist.append(oh)
     ohlist = newohlist
     bohlist = bencode(ohlist)
     chunk = self.read_chunk(index, begin, length)
     payload = tobinary(index) + tobinary(begin) + tobinary(
         len(bohlist)) + bohlist + chunk
     return EXTEND + HASHPIECE + payload
예제 #15
0
    def olthread_piece_data_connect_callback(self, exc, dns, permid,
                                             selversion, piece_number,
                                             piece_data):
        """ Sends the piece data message on the connections with the doe nodes
        
        Called by the overlay thread.
        
        @param exc: Peer reachable/unreachable information. None = peer reachable
        @param dns:
        @param permid: the permid of the doe
        @param selversion: selected Overlay protocol version
        @param piece_number: The number of the transmitted piece
        @param piece_data: The piece data
        """

        if exc is None:
            # Update delivered_pieces informatio
            self.delivered_pieces[permid][piece_number] = True

            # Create message according to protocol version
            message = PIECE_DATA + self.infohash + tobinary(
                piece_number) + piece_data[0:].tostring()

            if DEBUG:
                print >> sys.stderr, "proxy: olthread_piece_data_connect_callback: Sending PIECE_DATA to", show_permid_short(
                    permid)

            # Connect using Tribler Ovrlay Swarm
            self.overlay_bridge.send(permid, message,
                                     self.olthread_piece_data_send_callback)
        elif DEBUG:
            # The doe is unreachable
            print >> sys.stderr, "proxy: olthread_piece_data_connect_callback: error connecting to", show_permid_short(
                permid), exc
예제 #16
0
    def olthread_dropped_piece_connect_callback(self, exc, dns, permid,
                                                selversion, piece):
        """ Sends the dropped piece message on the connection with the doe
        
        Called by the overlay thread.
        
        @param exc: Peer reachable/unreachable information. None = peer reachable
        @param dns:
        @param permid: the permid of the doe
        @param selversion: selected Overlay protocol version
        @param piece: The number of the piece that will not be relayed
        """
        if exc is None:
            # Store the piece status
            self.dropped_pieces[permid][piece] = True

            # Create message according to protocol version
            message = DROPPED_PIECE + self.infohash + tobinary(piece)

            if DEBUG:
                print >> sys.stderr, "proxy: olthread_dropped_piece_connect_callback: Sending DROPPED_PIECE to", show_permid_short(
                    permid)

            # Connect using Tribler Ovrlay Swarm
            self.overlay_bridge.send(permid, message,
                                     self.olthread_dropped_piece_send_callback)
        elif DEBUG:
            # The doe is unreachable
            print >> sys.stderr, "proxy: olthread_relay_dropped_connect_callback: error connecting to", show_permid_short(
                permid), exc
예제 #17
0
 def _send_message(self, s):
     x.update("COUNTMSG", float(x.data["COUNTMSG"][0]) + 1)
     s = tobinary(len(s)) + s
     if self.partial_message:
         self.outqueue.append(s)
     else:
         self.connection.send_message_raw(s)
예제 #18
0
    def olthread_cancel_uploading_piece_connect_callback(
            self, exc, dns, permid, piece, selversion):
        """ Sends the cancel upload piece message on the connection with the peer
        
        Called by the overlay thread.
        
        @param exc: Peer reachable/unreachable information. None = peer reachable
        @param dns:
        @param permid: the permid of the proxy that is requested to cancel uploading a piece
        @param piece: the canceled piece number 
        @param selversion: selected Overlay protocol version
        """
        if exc is None:
            # Peer is reachable
            if DEBUG:
                print >> sys.stderr, "doe: olthread_cancel_uploading_piece_connect_callback sending a cancel request to", show_permid_short(
                    permid), "for piece", piece

            # Create message according to protocol version
            message = CANCEL_UPLOADING_PIECE + self.infohash + tobinary(piece)

            # Connect using Tribler Ovrlay Swarm
            self.overlay_bridge.send(
                permid, message,
                self.olthread_cancel_uploading_piece_send_callback)
        else:
            # Peer is unreachable
            if DEBUG:
                print >> sys.stderr, "doe: olthread_cancel_uploading_piece_connect_callback: error connecting to", show_permid_short(
                    permid), exc

            # Remove peer from the list of asked peers
            self.remove_unreachable_proxy(permid)
예제 #19
0
    def olthread_dropped_piece_connect_callback(self, exc, dns, permid, selversion, piece):
        """ Sends the dropped piece message on the connection with the doe
        
        Called by the overlay thread.
        
        @param exc: Peer reachable/unreachable information. None = peer reachable
        @param dns:
        @param permid: the permid of the doe
        @param selversion: selected Overlay protocol version
        @param piece: The number of the piece that will not be relayed
        """
        if exc is None:
            # Store the piece status
            self.dropped_pieces[permid][piece] = True
            
            # Create message according to protocol version
            message = DROPPED_PIECE + self.infohash + tobinary(piece)

            if DEBUG:
                print >> sys.stderr,"proxy: olthread_dropped_piece_connect_callback: Sending DROPPED_PIECE to", show_permid_short(permid)

            # Connect using Tribler Ovrlay Swarm
            self.overlay_bridge.send(permid, message, self.olthread_dropped_piece_send_callback)
        elif DEBUG:
            # The doe is unreachable
            print >> sys.stderr,"proxy: olthread_relay_dropped_connect_callback: error connecting to", show_permid_short(permid), exc
예제 #20
0
    def olthread_piece_data_connect_callback(self, exc, dns, permid, selversion, piece_number, piece_data):
        """ Sends the piece data message on the connections with the doe nodes
        
        Called by the overlay thread.
        
        @param exc: Peer reachable/unreachable information. None = peer reachable
        @param dns:
        @param permid: the permid of the doe
        @param selversion: selected Overlay protocol version
        @param piece_number: The number of the transmitted piece
        @param piece_data: The piece data
        """

        if exc is None:
            # Update delivered_pieces informatio
            self.delivered_pieces[permid][piece_number] = True
            
            # Create message according to protocol version
            message = PIECE_DATA + self.infohash + tobinary(piece_number) + piece_data[0:].tostring()

            if DEBUG:
                print >> sys.stderr,"proxy: olthread_piece_data_connect_callback: Sending PIECE_DATA to", show_permid_short(permid)

            # Connect using Tribler Ovrlay Swarm
            self.overlay_bridge.send(permid, message, self.olthread_piece_data_send_callback)
        elif DEBUG:
            # The doe is unreachable
            print >> sys.stderr,"proxy: olthread_piece_data_connect_callback: error connecting to", show_permid_short(permid), exc
예제 #21
0
    def olthread_cancel_uploading_piece_connect_callback(self, exc, dns, permid, piece, selversion):
        """ Sends the cancel upload piece message on the connection with the peer
        
        Called by the overlay thread.
        
        @param exc: Peer reachable/unreachable information. None = peer reachable
        @param dns:
        @param permid: the permid of the proxy that is requested to cancel uploading a piece
        @param piece: the canceled piece number 
        @param selversion: selected Overlay protocol version
        """
        if exc is None:
            # Peer is reachable
            if DEBUG:
                print >> sys.stderr, "doe: olthread_cancel_uploading_piece_connect_callback sending a cancel request to", show_permid_short(permid), "for piece", piece
            
            # Create message according to protocol version
            message = CANCEL_UPLOADING_PIECE + self.infohash + tobinary(piece)
            
            # Connect using Tribler Ovrlay Swarm
            self.overlay_bridge.send(permid, message, self.olthread_cancel_uploading_piece_send_callback)
        else:
            # Peer is unreachable
            if DEBUG:
                print >> sys.stderr, "doe: olthread_cancel_uploading_piece_connect_callback: error connecting to", show_permid_short(permid), exc

            # Remove peer from the list of asked peers
            self.remove_unreachable_proxy(permid)
예제 #22
0
 def _send_message(self, s):
     x.update("COUNTMSG", float(x.data["COUNTMSG"][0]) + 1)
     s = tobinary(len(s))+s
     if self.partial_message:
         self.outqueue.append(s)
     else:
         self.connection.send_message_raw(s)
예제 #23
0
 def __init__(self, port, cmd, param):
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     s.connect(('127.0.0.1', port))
     msg = cmd + ' ' + param
     sizedata = tobinary(len(msg))
     s.send(sizedata)
     s.send(msg)
     s.close()
예제 #24
0
 def __init__(self,port,msg,ipaddr='127.0.0.1'):
     #print >>sys.stderr, "[IPPORTMSG1]\t%s\t%s\t%s" % (ipaddr, port, msg)
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     s.connect((ipaddr,port))
     sizedata = tobinary(len(msg))
     #print >>sys.stderr, "[IPPORTMSG2]\t%s\t%s\t%s" % (ipaddr, port, msg)
     s.send(sizedata)
     s.send(msg)
     s.close()
예제 #25
0
 def __init__(self, port, msg, ipaddr='127.0.0.1'):
     #print >>sys.stderr, "[IPPORTMSG1]\t%s\t%s\t%s" % (ipaddr, port, msg)
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     s.connect((ipaddr, port))
     sizedata = tobinary(len(msg))
     #print >>sys.stderr, "[IPPORTMSG2]\t%s\t%s\t%s" % (ipaddr, port, msg)
     s.send(sizedata)
     s.send(msg)
     s.close()
예제 #26
0
    def send_partial(self, bytes):
        if self.connection.closed:
            return 0
        if self.partial_message is None:
            s = self.upload.get_upload_chunk()
            if s is None:
                return 0
            # Merkle: send hashlist along with piece in HASHPIECE message
            index, begin, hashlist, piece = s

            if self.use_g2g:
                # ----- G2G: record who we send this to
                self.g2g_sent_piece_part(self, index, begin, hashlist, piece)

                # ---- G2G: we are uploading len(piece) data of piece #index
                for c in self.connecter.connections.itervalues():
                    if not c.use_g2g:
                        continue

                    # include sending to self, because it should not be excluded from the statistics

                    c.queue_g2g_piece_xfer(index, begin, piece)

            if self.connecter.merkle_torrent:
                bhashlist = bencode(hashlist)
                self.partial_message = ''.join(
                    (tobinary(1 + 4 + 4 + 4 + len(bhashlist) + len(piece)),
                     HASHPIECE, tobinary(index), tobinary(begin),
                     tobinary(len(bhashlist)), bhashlist, piece.tostring()))
            else:
                self.partial_message = ''.join(
                    (tobinary(len(piece) + 9), PIECE, tobinary(index),
                     tobinary(begin), piece.tostring()))
            if DEBUG_NORMAL_MSGS:
                print 'sending chunk: ' + str(index) + ': ' + str(
                    begin) + '-' + str(begin + len(piece))

        if bytes < len(self.partial_message):
            self.connection.send_message_raw(self.partial_message[:bytes])
            self.partial_message = self.partial_message[bytes:]
            return bytes

        q = [self.partial_message]
        self.partial_message = None
        if self.send_choke_queued:
            self.send_choke_queued = False
            self.outqueue.append(tobinary(1) + CHOKE)
            self.upload.choke_sent()
            self.just_unchoked = 0
        q.extend(self.outqueue)
        self.outqueue = []
        q = ''.join(q)
        self.connection.send_message_raw(q)
        return len(q)
예제 #27
0
 def write_extend_message(self, metadata_message_id, payload):
     assert isinstance(payload, dict), "PAYLOAD has invalid type: %s" % type(payload)
     assert isinstance(metadata_message_id, str), "METADATA_MESSAGE_ID has invalid type: %s" % type(metadata_message_id)
     assert len(metadata_message_id) == 1, "METADATA_MESSAGE_ID has invalid length: %d" % len(metadata_message_id)
     if DEBUG: print >> sys.stderr, self._address, "MiniBitTorrent.write_extend_message()"
     payload = bencode(payload)
     self._socket.write("".join((tobinary(2 + len(payload)), # msg len
                                 EXTEND,                     # msg id
                                 metadata_message_id,        # extend msg id
                                 payload)))                  # bencoded msg
예제 #28
0
 def __init__(self,port,cmd,param):
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     s.connect(('127.0.0.1',port))
     msg = cmd+' '+param
     sizedata = tobinary(len(msg))
     s.send(sizedata)
     s.send(msg)
     s.close()
     
     
예제 #29
0
    def create_good_hashpiece(self,oldstyle,chunkid):
        index, begin, length = chunkid
        if begin == 0:
            ohlist = self.tree.get_hashes_for_piece(index)
        else:
            ohlist = []

        chunk = self.read_chunk(index,begin,length)
        bohlist = bencode(ohlist)
        
        print >>sys.stderr,"test: create_good_hashpiece:",index,begin,length,"==len",len(chunk)

        payload = tobinary(index)+tobinary(begin)+tobinary(len(bohlist))+bohlist+chunk
        if oldstyle:
            msg = HASHPIECE+payload
        else:
            # Offical: use the msg ID he defined in his handshake
            msg = EXTEND+HASHPIECE+payload
        return msg
예제 #30
0
    def send_partial(self, bytes):
        if self.connection.closed:
            return 0
        if self.partial_message is None:
            s = self.upload.get_upload_chunk()
            if s is None:
                return 0
            # Merkle: send hashlist along with piece in HASHPIECE message
            index, begin, hashlist, piece = s

            if self.use_g2g:
                # ----- G2G: record who we send this to
                self.g2g_sent_piece_part( self, index, begin, hashlist, piece )

                # ---- G2G: we are uploading len(piece) data of piece #index
                for c in self.connecter.connections.itervalues():
                    if not c.use_g2g:
                        continue

                    # include sending to self, because it should not be excluded from the statistics

                    c.queue_g2g_piece_xfer( index, begin, piece )

            if self.connecter.merkle_torrent:
                bhashlist = bencode(hashlist)
                self.partial_message = ''.join((
                                tobinary(1+4+4+4+len(bhashlist)+len(piece)), HASHPIECE,
                                tobinary(index), tobinary(begin), tobinary(len(bhashlist)), bhashlist, piece.tostring() ))
            else:
                self.partial_message = ''.join((
                            tobinary(len(piece) + 9), PIECE, 
                            tobinary(index), tobinary(begin), piece.tostring()))
            if DEBUG_NORMAL_MSGS:
                print 'sending chunk: '+str(index)+': '+str(begin)+'-'+str(begin+len(piece))

        if bytes < len(self.partial_message):
            self.connection.send_message_raw(self.partial_message[:bytes])
            self.partial_message = self.partial_message[bytes:]
            return bytes

        q = [self.partial_message]
        self.partial_message = None
        if self.send_choke_queued:
            self.send_choke_queued = False
            self.outqueue.append(tobinary(1)+CHOKE)
            self.upload.choke_sent()
            self.just_unchoked = 0
        q.extend(self.outqueue)
        self.outqueue = []
        q = ''.join(q)
        self.connection.send_message_raw(q)
        return len(q)
    def create_good_hashpiece(self, oldstyle, chunkid):
        index, begin, length = chunkid
        if begin == 0:
            ohlist = self.tree.get_hashes_for_piece(index)
        else:
            ohlist = []

        chunk = self.read_chunk(index, begin, length)
        bohlist = bencode(ohlist)

        print >> sys.stderr, "test: create_good_hashpiece:", index, begin, length, "==len", len(
            chunk)

        payload = tobinary(index) + tobinary(begin) + tobinary(
            len(bohlist)) + bohlist + chunk
        if oldstyle:
            msg = HASHPIECE + payload
        else:
            # Offical: use the msg ID he defined in his handshake
            msg = EXTEND + HASHPIECE + payload
        return msg
예제 #32
0
 def write_extend_message(self, metadata_message_id, payload):
     assert isinstance(payload,
                       dict), "PAYLOAD has invalid type: %s" % type(payload)
     assert isinstance(
         metadata_message_id,
         str), "METADATA_MESSAGE_ID has invalid type: %s" % type(
             metadata_message_id)
     assert len(metadata_message_id
                ) == 1, "METADATA_MESSAGE_ID has invalid length: %d" % len(
                    metadata_message_id)
     if DEBUG:
         print >> sys.stderr, self._address, "MiniBitTorrent.write_extend_message()"
     payload = bencode(payload)
     self._socket.write("".join((
         tobinary(2 + len(payload)),  # msg len
         EXTEND,  # msg id
         metadata_message_id,  # extend msg id
         payload)))  # bencoded msg
예제 #33
0
 def send_cancel(self, index, begin, length):
     self._send_message(CANCEL + tobinary(index) + 
         tobinary(begin) + tobinary(length))
     if DEBUG_NORMAL_MSGS:
         print 'sent cancel: '+str(index)+': '+str(begin)+'-'+str(begin+length)
 def create_not_len_bohlist(self, chunkid):
     index, begin, length = chunkid
     payload = tobinary(index) + tobinary(begin) + 'bla'
     return EXTEND + HASHPIECE + payload
예제 #35
0
 def create_request(self,chunkid):
     index,begin,length = chunkid
     return REQUEST+tobinary(index)+tobinary(begin)+tobinary(length)
 def create_request(self, chunkid):
     index, begin, length = chunkid
     return REQUEST + tobinary(index) + tobinary(begin) + tobinary(length)
예제 #37
0
 def send_g2g_piece_xfer_v1(self,index,begin,piece):
     """ Send fact that we sent piece index[begin:begin+chunk] to a peer
     to all peers (G2G V1).
     """
     self._send_message(self.his_extend_msg_name_to_id(EXTEND_MSG_G2G_V1) + tobinary(index) + tobinary(begin) + tobinary(len(piece)))
예제 #38
0
 def create_not_len_bohlist(self,chunkid):
     index,begin,length = chunkid
     payload = tobinary(index)+tobinary(begin)+'bla'
     return EXTEND+HASHPIECE+payload
예제 #39
0
 def send_cancel(self, index, begin, length):
     self._send_message(CANCEL + tobinary(index) + tobinary(begin) +
                        tobinary(length))
     if DEBUG_NORMAL_MSGS:
         print 'sent cancel: ' + str(index) + ': ' + str(begin) + '-' + str(
             begin + length)
예제 #40
0
 def send_have(self, index):
     #print_stack()
     self._send_message(HAVE + tobinary(index))
예제 #41
0
 def send_have(self, index):
     #print_stack()
     self._send_message(HAVE + tobinary(index))
예제 #42
0
 def send_message(self,message):
     self.last_use = time()
     s = tobinary(len(message))+message
     if DEBUG:
         print >> sys.stderr,"dlbconn: Sending message",len(message)
     self.write(s)
예제 #43
0
 def create_ohlist_not_bdecodable(self,chunkid):
     index,begin,length = chunkid
     bohlist = 'bla'
     chunk = '*' * (2 ** 14)
     payload = tobinary(index)+tobinary(begin)+tobinary(len(bohlist))+bohlist+chunk
     return EXTEND+HASHPIECE+payload