Ejemplo n.º 1
0
 def messageHandler(self, sSocket):
     serverAddr= sSocket.getpeername()[0]
     serverPort=sSocket.getpeername()[1]
     sSocket.send(messages.version_pkt(MY_IP, serverAddr,serverPort).to_bytes())
     
     
     while True:
         dataReceived = sSocket.recv(1024)
         if not dataReceived:
             #will close the socket
             break;
         msg = MsgSerializable().from_bytes(dataReceived)
         print('on_new_server')
         print('received ',msg)
         if isinstance(msg,msg_version):
             self.outbound_connections.add(serverAddr)
             sSocket.send(msg_verack().to_bytes())
             print('sent verack')
             sSocket.send(msg_getaddr().to_bytes())
             print('sent msg_getaddr')
         if isinstance(msg,msg_addr):
             for peer in msg.addrs:
                 if peer.ip not in self.outbound_connections and peer.ip != MY_IP:
                     print('new peer found'+peer.ip)
                     t = threading.Thread(target=self.connect,args=(peer.ip, peer.port))
                     t.start()
                     
                 
         time.sleep(SLEEP_TIME)
     sSocket.close()
     
Ejemplo n.º 2
0
 def _handle_pkt(self, pkt):
     if isinstance(pkt, messages.msg_version):
         self.ver_pkt = pkt
         self.last_useful = time.time()
         return messages.msg_verack()
     elif isinstance(pkt, messages.msg_ping):
         return messages.msg_pong(nonce=pkt.nonce)
     elif isinstance(pkt, messages.msg_verack):
         self.verack_received = True
         self.last_useful = time.time()
         return None
     elif isinstance(pkt, messages.msg_addr):
         if len(pkt.addrs) > 10:
             self._handle_addr(pkt)
             return False  # disconnect, we got what we wanted
         else:
             return None  # usually either forwarded or self-announcement, neither is useful
     elif isinstance(pkt, (messages.msg_getheaders, messages.msg_inv,
                           messages.msg_alert, messages.msg_getblocks)):
         pass  # irrelevant but common, don't want to spam log
     else:
         log.debug(f'other pkt from -> {self.ip}: {pkt}')
     if self.pkt_count > 6 and not self.getaddr_sent:
         self.getaddr_sent = True
         # some clients advertise their own address first, and only then seem to properly react to getaddr
         # and sometimes it seems to be unrelated to that, so just wait a few packets, then it usually
         # works, except for clients that just don't reply at all, which also happens
         # (which is why we have last_useful to expire connections that don't yield addresses in reasonable time)
         return messages.msg_getaddr()
     return None
Ejemplo n.º 3
0
	def listen_until_addresses(self):
		"""Implements the Bitcoin protocol, sending info until it gets an addr message"""
		

		# Try to get addresses
		self.my_socket.send(msg_getaddr().to_bytes())

		while not self._process_message():  # TODO set timeout or something for multiple addr messages
			pass
		self.my_socket.close()
Ejemplo n.º 4
0
 def send_getaddr(self):
     self.send_message(msg_getaddr())
Ejemplo n.º 5
0
    def got_message(self, message):
        gevent.sleep()

        if self.last_sent + 30 * 60 < time.time():
            self.send_message(messages.msg_ping(self.ver_send))

        self.log.debug("recv %s" % repr(message))

        if message.command == "version":
            self.ver_send = min(self.params.PROTO_VERSION, message.nVersion)
            if self.ver_send < self.params.MIN_PROTO_VERSION:
                self.log.info("Obsolete version %d, closing" %
                              (self.ver_send,))
                self.handle_close()
                return

            if (self.ver_send >= self.params.NOBLKS_VERSION_START and
                    self.ver_send <= self.params.NOBLKS_VERSION_END):
                self.getblocks_ok = False

            self.remote_height = message.nStartingHeight
            self.send_message(messages.msg_verack(self.ver_send))
            if self.ver_send >= self.params.CADDR_TIME_VERSION:
                self.send_message(messages.msg_getaddr(self.ver_send))
            self.request_latest()
            self.client_version = message.strSubVer

        elif message.command == "verack":
            self.ver_recv = self.ver_send

            if self.ver_send >= self.params.MEMPOOL_GD_VERSION:
                self.send_message(messages.msg_mempool())

        elif message.command == "ping":
            if self.ver_send > self.params.BIP0031_VERSION:
                self.send_message(messages.msg_pong(self.ver_send))

        elif message.command == "addr":
            self.peermgr.new_addrs(message.addrs)

        elif message.command == "inv":

            # special message sent to kick getblocks
            if (len(message.inv) == 1 and
                    message.inv[0].type == messages.MSG_BLOCK and
                    self.chaindb.haveblock(message.inv[0].hash, True)):
                self.request_latest(False)
                return

            want = messages.msg_getdata(self.ver_send)
            for i in message.inv:
                if i.type == 1:
                    want.inv.append(i)
                elif i.type == 2:
                    want.inv.append(i)
            if len(want.inv):
                self.send_message(want)

        elif message.command == "tx":
            if self.chaindb.tx_is_orphan(message.tx):
                self.log.info(
                    "MemPool: Ignoring orphan TX {}"
                    .format(message.tx.GetHash().encode('hex')))
            elif not self.chaindb.tx_signed(message.tx, None, True):
                self.log.info(
                    "MemPool: Ignoring failed-sig TX {}"
                    .format(message.tx.GetHash().encode('hex')))
            else:
                self.mempool.add(message.tx)

        elif message.command == "block":
            self.chaindb.putblock(message.block)
            self.last_block_rx = time.time()

        elif message.command == "headers":
            self.chaindb.putblock(message.block)
            self.last_block_rx = time.time()

        elif message.command == "getdata":
            self.getdata(message)

        elif message.command == "getblocks":
            self.getblocks(message)

        elif message.command == "getheaders":
            self.getheaders(message)

        elif message.command == "getaddr":
            msg = messages.msg_addr()
            msg.addrs = self.peermgr.random_addrs()

            self.send_message(msg)

        elif message.command == "mempool":
            msg = messages.msg_inv()
            for k in self.mempool.pool.iterkeys():
                inv = net.CInv()
                inv.type = messages.MSG_TX
                inv.hash = k
                msg.inv.append(inv)

                if len(msg.inv) == 50000:
                    break

            self.send_message(msg)

        # if we haven't seen a 'block' message in a little while,
        # and we're still not caught up, send another getblocks
        last_blkmsg = time.time() - self.last_block_rx
        if last_blkmsg > 5:
            self.request_latest()
Ejemplo n.º 6
0
    def got_message(self, message):
        gevent.sleep()

        if self.last_sent + 30 * 60 < time.time():
            self.send_message(msg_ping(self.ver_send))

        if verbose_recvmsg(message):
            self.log.info("recv %s" % repr(message))

        if message.command == b"version":
            self.ver_send = min(PROTO_VERSION, message.nVersion)
            if self.ver_send < MIN_PROTO_VERSION:
                self.log.info("Obsolete version %d, closing" %
                              (self.ver_send, ))
                self.handle_close()
                return

            self.remote_height = message.nStartingHeight
            self.send_message(msg_verack(self.ver_send))

            if self.ver_send >= CADDR_TIME_VERSION:
                self.send_message(msg_getaddr(self.ver_send))

            # self.send_getblocks()

        elif message.command == b'ping':
            if self.ver_send > BIP0031_VERSION:
                self.send_message(msg_pong(self.ver_send))

        elif message.command == b"verack":
            self.ver_recv = self.ver_send
            self.send_message(msg_addr())
            self.send_getaddr()

        elif message.command == b"inv":

            # special message sent to kick getblocks
            # if (len(message.inv) == 1 and
            #     message.inv[0].type == MSG_BLOCK and
            #     self.chaindb.haveblock(message.inv[0].hash, True)):
            #     self.send_getblocks(False)
            #     return

            want = msg_getdata(self.ver_send)
            for i in message.inv:
                if i.type == 1:
                    want.inv.append(i)
                elif i.type == 2:
                    want.inv.append(i)
                self.last_want = i.hash
            if len(want.inv):
                self.send_message(want)

        # elif message.command == b"block":
        #     bhash = b2lx(message.block.GetHash())
        #     self.chaindb.putblock(message.block)
        #     self.last_block_rx = time.time()
        #     if self.last_want == 0:
        #         gevent.spawn(self.send_getblocks)
        #     elif bhash == b2lx(self.last_want):
        #         gevent.spawn(self.send_getblocks)
        elif message.command == b"addr":
            self.peermgr.new_addrs(message.addrs)
            for addr in message.addrs:
                self.peermgr.add(addr.ip, addr.port)
        elif message.command == b'getheaders':
            self.send_message(msg_headers())
Ejemplo n.º 7
0
    def got_message(self, message):
        gevent.sleep()

        if self.last_sent + 30 * 60 < time.time():
            self.send_message(messages.msg_ping(self.ver_send))

        self.log.debug("recv %s" % repr(message))

        if message.command == "version":
            self.ver_send = min(self.params.PROTO_VERSION, message.nVersion)
            if self.ver_send < self.params.MIN_PROTO_VERSION:
                self.log.info("Obsolete version %d, closing" %
                              (self.ver_send, ))
                self.handle_close()
                return

            if (self.ver_send >= self.params.NOBLKS_VERSION_START
                    and self.ver_send <= self.params.NOBLKS_VERSION_END):
                self.getblocks_ok = False

            self.remote_height = message.nStartingHeight
            self.send_message(messages.msg_verack(self.ver_send))
            if self.ver_send >= self.params.CADDR_TIME_VERSION:
                self.send_message(messages.msg_getaddr(self.ver_send))
            self.request_latest()
            self.client_version = message.strSubVer

        elif message.command == "verack":
            self.ver_recv = self.ver_send

            if self.ver_send >= self.params.MEMPOOL_GD_VERSION:
                self.send_message(messages.msg_mempool())

        elif message.command == "ping":
            if self.ver_send > self.params.BIP0031_VERSION:
                self.send_message(messages.msg_pong(self.ver_send))

        elif message.command == "addr":
            self.peermgr.new_addrs(message.addrs)

        elif message.command == "inv":

            # special message sent to kick getblocks
            if (len(message.inv) == 1
                    and message.inv[0].type == messages.MSG_BLOCK
                    and self.chaindb.haveblock(message.inv[0].hash, True)):
                self.request_latest(False)
                return

            want = messages.msg_getdata(self.ver_send)
            for i in message.inv:
                if i.type == 1:
                    want.inv.append(i)
                elif i.type == 2:
                    want.inv.append(i)
            if len(want.inv):
                self.send_message(want)

        elif message.command == "tx":
            if self.chaindb.tx_is_orphan(message.tx):
                self.log.info("MemPool: Ignoring orphan TX {}".format(
                    message.tx.GetHash().encode('hex')))
            elif not self.chaindb.tx_signed(message.tx, None, True):
                self.log.info("MemPool: Ignoring failed-sig TX {}".format(
                    message.tx.GetHash().encode('hex')))
            else:
                self.mempool.add(message.tx)

        elif message.command == "block":
            self.chaindb.putblock(message.block)
            self.last_block_rx = time.time()

        elif message.command == "headers":
            self.chaindb.putblock(message.block)
            self.last_block_rx = time.time()

        elif message.command == "getdata":
            self.getdata(message)

        elif message.command == "getblocks":
            self.getblocks(message)

        elif message.command == "getheaders":
            self.getheaders(message)

        elif message.command == "getaddr":
            msg = messages.msg_addr()
            msg.addrs = self.peermgr.random_addrs()

            self.send_message(msg)

        elif message.command == "mempool":
            msg = messages.msg_inv()
            for k in self.mempool.pool.iterkeys():
                inv = net.CInv()
                inv.type = messages.MSG_TX
                inv.hash = k
                msg.inv.append(inv)

                if len(msg.inv) == 50000:
                    break

            self.send_message(msg)

        # if we haven't seen a 'block' message in a little while,
        # and we're still not caught up, send another getblocks
        last_blkmsg = time.time() - self.last_block_rx
        if last_blkmsg > 5:
            self.request_latest()