示例#1
0
 def _handle_recv(self):
     while True:
         try:
             msg = MsgSerializable.stream_deserialize(
                 self.conn.makefile(mode='r'),
                 protover=self.protover)
         except Exception as e:
             msg = e
             if not self._stopflag.is_set():
                 print("Peer connection closed unexpectedly.")
             break
         finally:
             self.recvq.put(msg)
示例#2
0
	def _process_message(self, **kwargs):
		msg = MsgSerializable.stream_deserialize(Wrapper(self.my_socket))

		if msg.command == b"version":  # TODO conglomerate these message strings into a dictionary
		    # Send Verack
		    # print('version: ', msg.strSubVer, msg.nVersion)
		    self.my_socket.send( msg_verack().to_bytes() )
		    return "version"
		elif msg.command == b"verack":
		    # print("verack: ", msg)
		    return "verack"
		elif msg.command == b"inv":
			pass
			# print("inv: ", msg.inv)
			# print(dir(msg))
			# print(type(msg.inv))
		elif msg.command == b"ping":
			# print("ping: ", msg)
			self.my_socket.send(msg_pong(msg.nonce).to_bytes())

		elif msg.command == b"getheaders":
			pass
			# print("getheaders received ")

		elif msg.command == b"addr":  # TODO this needs multi-message support
			# print("addr: size ", len(msg.addrs))
			for address in msg.addrs:
				node = Link(address.ip, address.port)
				self.results.add(node)
			return True
		elif msg.command == b"getdata":
			# print("getdata: ", msg.inv)
			if 'transaction' not in kwargs:
				return False
			the_tx =  kwargs['transaction']
			for request in msg.inv:
				if request.hash == the_tx.GetHash():
					print(threading.current_thread().name,"sending tx: ", self.link)
					# new message to send transaction
					to_send = msg_tx()
					to_send.tx = the_tx
					self.my_socket.send(to_send.to_bytes())
					# print("SENT OUR PC BRO TRANSACTION")
					return "donedone"
		else:
		    pass
		    # print("something else: ", msg.command, msg)

		return False
示例#3
0
 def process_data(self):
     while True:
         if len(self.recvbuf) < 4:
             return
         if self.recvbuf[:4] != self.netmagic.MESSAGE_START:
             raise ValueError("got garbage %s" % repr(self.recvbuf))
         if len(self.recvbuf) < 4 + 12 + 4 + 4:
             return
         msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0]
         if len(self.recvbuf) < 4 + 12 + 4 + 4 + msglen:
             return
         message = self.recvbuf[:4+12+4+4+msglen]
         self.recvbuf = self.recvbuf[4+12+4+4+msglen:]
         f = BytesIO(message)
         try:
             msg = MsgSerializable.stream_deserialize(f)
         except ValueError:
             raise ValueError("invalid deserialization %s" % repr(self.recvbuf))  # noqa
         if msg is None:
             return
         self.got_message(msg)
示例#4
0
 def process_data(self):
     while True:
         if len(self.recvbuf) < 4:
             return
         if self.recvbuf[:4] != self.netmagic.MESSAGE_START:
             raise ValueError("got garbage %s" % repr(self.recvbuf))
         if len(self.recvbuf) < 4 + 12 + 4 + 4:
             return
         msglen = struct.unpack("<i", self.recvbuf[4 + 12:4 + 12 + 4])[0]
         if len(self.recvbuf) < 4 + 12 + 4 + 4 + msglen:
             return
         message = self.recvbuf[:4 + 12 + 4 + 4 + msglen]
         self.recvbuf = self.recvbuf[4 + 12 + 4 + 4 + msglen:]
         f = BytesIO(message)
         try:
             msg = MsgSerializable.stream_deserialize(f)
         except ValueError:
             raise ValueError("invalid deserialization %s" %
                              repr(self.recvbuf))  # noqa
         if msg is None:
             return
         self.got_message(msg)
示例#5
0
    def getblock(self, blkhash) -> CBlock:
        # block = self.blk_cache.get(blkhash)
        # if block is not None:
        #     return block

        ser_hash = b2lx(blkhash)
        try:
            # Lookup the block index, seek in the file
            fpos = self.db.get(('blocks:'+ser_hash).encode())
            fpos = struct.unpack('i', fpos)[0]
            self.blk_read.seek(fpos)
            # read and decode "block" msg
            msg = MsgSerializable.stream_deserialize(self.blk_read)
            if msg is None:
                return None
            block = msg.block
        except KeyError:
            return None

        # self.blk_cache.put(blkhash, block)

        return block
 def test_read_msg_verack(self):
     f = BytesIO(self.verackbytes)
     m = MsgSerializable.stream_deserialize(f)
     self.assertEqual(m.command, msg_verack.command)
示例#7
0
 def test_fail_invalid_message(self):
     bad_verack_bytes = b'\xf8' + self.verackbytes[1:]
     f = BytesIO(bad_verack_bytes)
     with self.assertRaises(ValueError):
         MsgSerializable.stream_deserialize(f)
示例#8
0
    def run(self):
        try:
            self.s.connect((self.addr.ip, self.addr.port))
            version_pkt(self.addr.ip, self.addr.port).stream_serialize(self.s)
        except Exception as e:
            print(e)
            print("{}, {}: Version handshake failed with {}:{}".format(datetime.datetime.now(), self.name, self.addr.ip, self.addr.port))
            self._stop_request.set()

        # Make sure we dont send an addr or inv straight away
        self.lastaddr = time.time()
        self.lastinv = time.time()

        while not self._stop_request.is_set():
            # Send at most one of these three
            if time.time() - self.lastping > PING_INTERVAL:
                msg_ping(random.getrandbits(64)).stream_serialize(self.s)
                self.lastping = time.time()
            elif time.time() - self.lastaddr > ADDR_INTERVAL:
                out = msg_addr()
                # Grab 10 random addresses
                with address_lock:
                    random_addresses = random.sample(addresses, min(10, len(addresses)))
                for address in random_addresses:
                    caddr = CAddress()
                    # Lie a bit
                    caddr.nTime = int(time.time()) - random.randrange(300)
                    caddr.nServices = address.services
                    caddr.port = address.port
                    caddr.ip = address.ip
                    out.addrs.append(caddr)
                out.stream_serialize(self.s)
                self.lastaddr = time.time()
            elif time.time() - self.lastinv > INV_INTERVAL:
                out = msg_inv()
                out_inv = CInv()
                out_inv.type = BLOCK_TYPE
                out_inv.hash = guess_latest_block()
                out.inv = [out_inv]
                out.stream_serialize(self.s)
                self.lastinv = time.time()
            try:
                msg = MsgSerializable.stream_deserialize(self.s)
                t = time.time()

                if isinstance(msg, msg_version):
                    msg_verack().stream_serialize(self.s)
                elif isinstance(msg, msg_verack):
                    print("{}, {}: Version handshake complete".format(datetime.datetime.now(), self.name))
                elif isinstance(msg, msg_ping):
                    result = push({
                        "me": {
                            "ip": my_ipv4,
                            "port": my_port
                        },
                        "time": t,
                        "type": "ping",
                        "peer": {
                            "ip": self.addr.ip,
                            "port": self.addr.port
                        },
                        "last": {
                            "ping": self.lastping,
                            "inv": self.lastinv,
                            "addr": self.lastaddr
                        },
                        "raw": base64.b64encode(msg.to_bytes()).decode('utf-8'),
                        "data": msg.nonce
                    })
                    msg_pong(nonce=msg.nonce).stream_serialize(self.s)
                elif isinstance(msg, msg_pong):
                    result = push({
                        "me": {
                            "ip": my_ipv4,
                            "port": my_port
                        },
                        "time": t,
                        "type": "pong",
                        "peer": {
                            "ip": self.addr.ip,
                            "port": self.addr.port
                        },
                        "last": {
                            "ping": self.lastping,
                            "inv": self.lastinv,
                            "addr": self.lastaddr
                        },
                        "raw": base64.b64encode(msg.to_bytes()).decode('utf-8'),
                        "data": msg.nonce
                    })
                elif isinstance(msg, msg_getheaders):
                    pass
                elif isinstance(msg, msg_alert):
                    pass
                elif isinstance(msg, msg_inv):
                    if any(item.type == BLOCK_TYPE for item in msg.inv):
                        result = push({
                            "me": {
                                "ip": my_ipv4,
                                "port": my_port
                            },
                            "time": t,
                            "type": "inv",
                            "peer": {
                                "ip": self.addr.ip,
                                "port": self.addr.port
                            },
                            "last": {
                                "ping": self.lastping,
                                "inv": self.lastinv,
                                "addr": self.lastaddr
                            },
                            "raw": base64.b64encode(msg.to_bytes()).decode('utf-8'),
                            "data": [
                                {
                                    "type": "block" if item.type == BLOCK_TYPE else "tx",
                                    "hash": b2lx(item.hash)
                                } for item in msg.inv
                            ]
                        })
                    for inv in msg.inv:
                        if inv.type == BLOCK_TYPE:
                            append_latest_block(inv.hash)
                elif isinstance(msg, msg_addr):
                    discover_new_addresses(msg.addrs)
                else:
                    print("{}, {}: Unhandled message type: {}".format(datetime.datetime.now(), self.name, msg.command.decode('utf-8')))
            except socket.timeout:
                continue
            except SerializationTruncationError:
                print("{}, {}: **************** Socket closed. ****************".format(datetime.datetime.now(), self.name))
                break
        self.s.close()
        print("{}, {}: Stopped.".format(datetime.datetime.now(), self.name))