def messageHandler(self, clientsocket, addr): while True: dataReceived = clientsocket.recv(1024) if not dataReceived: #will close the socket break; msg = MsgSerializable().from_bytes(dataReceived) print('received ',msg) print( isinstance(msg,msg_version)) if isinstance(msg,msg_version): clientsocket.send(msg_verack().to_bytes()) self.inbound_connections.add(addr[0]) print('sent verack') clientsocket.send( messages.version_pkt(MY_IP, addr[0],self.port).to_bytes() ) print('sent version_pkt') if isinstance(msg,msg_getaddr): perrAddrs = [] for peer in self.inbound_connections: perrAddr = CAddress() perrAddr.port=self.port perrAddr.nTime = int(time.time()) perrAddr.ip = peer perrAddrs.append(perrAddr) rMsg= msg_addr() rMsg.addrs = perrAddrs print(rMsg) clientsocket.send(rMsg.to_bytes()) print('sent msg_addr') time.sleep(SLEEP_TIME) clientsocket.close()
def remote_caddress(self): caddress = CAddress() caddress.nTime = self.connect_time # TODO: Set the remote address ip # caddress.ip = caddress.port = self.remote_address.port return caddress
def __init__(self, protover=PROTO_VERSION): super(msg_version, self).__init__(protover) self.nVersion = protover self.nServices = 1 self.nTime = int(time.time()) self.addrTo = CAddress(PROTO_VERSION) self.addrFrom = CAddress(PROTO_VERSION) self.nNonce = random.getrandbits(64) self.strSubVer = b"/python-bitcoinlib:" + bitcoin.__version__.encode("ascii") + b"/" self.nStartingHeight = -1
def __init__(self, protover=PROTO_VERSION): super(msg_version, self).__init__(protover) self.nVersion = protover self.nServices = 1 self.nTime = int(time.time()) self.addrTo = CAddress(PROTO_VERSION) self.addrFrom = CAddress(PROTO_VERSION) self.nNonce = random.getrandbits(64) self.strSubVer = (b'/python-bitcoinlib:' + bitcoin.__version__.encode('ascii') + b'/') self.nStartingHeight = -1
def addr_pkt(str_addrs): msg = msg_addr() addrs = [] for i in str_addrs: addr = CAddress() addr.port = 8333 addr.nTime = int(time.time()) addr.ip = i addrs.append(addr) msg.addrs = addrs return msg
def addr_pkt( str_addrs ): msg = msg_addr() addrs = [] for i in str_addrs: addr = CAddress() addr.port = 18333 addr.nTime = int(time.time()) addr.ip = i addrs.append( addr ) msg.addrs = addrs return msg
class msg_version(MsgSerializable): command = b"version" def __init__(self, protover=PROTO_VERSION): super(msg_version, self).__init__(protover) self.nVersion = protover self.nServices = 1 self.nTime = int(time.time()) self.addrTo = CAddress(PROTO_VERSION) self.addrFrom = CAddress(PROTO_VERSION) self.nNonce = random.getrandbits(64) self.strSubVer = (b'/python-bitcoinlib:' + bitcoin.__version__.encode('ascii') + b'/') self.nStartingHeight = -1 @classmethod def msg_deser(cls, f, protover=PROTO_VERSION): c = cls() c.nVersion = struct.unpack(b"<i", ser_read(f, 4))[0] if c.nVersion == 10300: c.nVersion = 300 c.nServices = struct.unpack(b"<Q", ser_read(f, 8))[0] c.nTime = struct.unpack(b"<q", ser_read(f, 8))[0] c.addrTo = CAddress.stream_deserialize(f, True) if c.nVersion >= 106: c.addrFrom = CAddress.stream_deserialize(f, True) c.nNonce = struct.unpack(b"<Q", ser_read(f, 8))[0] c.strSubVer = VarStringSerializer.stream_deserialize(f) if c.nVersion >= 209: c.nStartingHeight = struct.unpack(b"<i", ser_read(f,4))[0] else: c.nStartingHeight = None else: c.addrFrom = None c.nNonce = None c.strSubVer = None c.nStartingHeight = None return c def msg_ser(self, f): f.write(struct.pack(b"<i", self.nVersion)) f.write(struct.pack(b"<Q", self.nServices)) f.write(struct.pack(b"<q", self.nTime)) self.addrTo.stream_serialize(f, True) self.addrFrom.stream_serialize(f, True) f.write(struct.pack(b"<Q", self.nNonce)) VarStringSerializer.stream_serialize(self.strSubVer, f) f.write(struct.pack(b"<i", self.nStartingHeight)) def __repr__(self): return "msg_version(nVersion=%i nServices=%i nTime=%s addrTo=%s addrFrom=%s nNonce=0x%016X strSubVer=%s nStartingHeight=%i)" % (self.nVersion, self.nServices, time.ctime(self.nTime), repr(self.addrTo), repr(self.addrFrom), self.nNonce, self.strSubVer, self.nStartingHeight)
def btc_addr_pkt(s, str_addrs): pkt = msg_addr() addrs = [] for i in str_addrs: addr = CAddress() addr.port = s.dport addr.nTime = int(time.time()) addr.ip = i addrs.append( addr ) pkt.addrs = addrs pkt.to_bytes() return s.btc_add_magic(pkt)
def __init__( self, nServices=1, nTime=None, addrTo=None, addrFrom=None, nNonce=None, strSubVer=USER_AGENT, nStartingHeight=-1, protover=PROTO_VERSION, ): super(msg_version, self).__init__(protover) self.nVersion = protover self.nServices = nServices self.nTime = nTime or int(time.time()) self.addrTo = addrTo or CAddress(PROTO_VERSION) self.addrFrom = addrFrom or CAddress(PROTO_VERSION) self.nNonce = nNonce or random.SystemRandom().getrandbits(64) self.strSubVer = strSubVer self.nStartingHeight = nStartingHeight
def msg_deser(cls, f, protover=PROTO_VERSION): c = cls() c.nVersion = struct.unpack(b"<i", ser_read(f, 4))[0] if c.nVersion == 10300: c.nVersion = 300 c.nServices = struct.unpack(b"<Q", ser_read(f, 8))[0] c.nTime = struct.unpack(b"<q", ser_read(f, 8))[0] c.addrTo = CAddress.stream_deserialize(f, True) if c.nVersion >= 106: c.addrFrom = CAddress.stream_deserialize(f, True) c.nNonce = struct.unpack(b"<Q", ser_read(f, 8))[0] c.strSubVer = VarStringSerializer.stream_deserialize(f) if c.nVersion >= 209: c.nStartingHeight = struct.unpack(b"<i", ser_read(f, 4))[0] else: c.nStartingHeight = None else: c.addrFrom = None c.nNonce = None c.strSubVer = None c.nStartingHeight = None return c
def msg_deser(cls, f, protover=PROTO_VERSION): c = cls() c.nVersion = struct.unpack(b"<i", ser_read(f, 4))[0] if c.nVersion == 10300: c.nVersion = 300 c.nServices = struct.unpack(b"<Q", ser_read(f, 8))[0] c.nTime = struct.unpack(b"<q", ser_read(f, 8))[0] c.addrTo = CAddress.stream_deserialize(f, True) if c.nVersion >= 106: c.addrFrom = CAddress.stream_deserialize(f, True) c.nNonce = struct.unpack(b"<Q", ser_read(f, 8))[0] c.strSubVer = VarStringSerializer.stream_deserialize(f) if c.nVersion >= 209: c.nStartingHeight = struct.unpack(b"<i", ser_read(f,4))[0] else: c.nStartingHeight = None else: c.addrFrom = None c.nNonce = None c.strSubVer = None c.nStartingHeight = None return c
def test_serializationIPv6(self): c = CAddress() c.ip = "1234:ABCD:1234:ABCD:1234:00:ABCD:1234" c.port = 8333 c.nTime = 1420576401 cSerialized = c.serialize() cDeserialized = CAddress.deserialize(cSerialized) self.assertEqual(c, cDeserialized) cSerializedTwice = cDeserialized.serialize() self.assertEqual(cSerialized, cSerializedTwice)
def do_connect(client_addr, server_addr, nonce): global INV_SEND_TS, g_ver_ts, g_getaddr_send_ts with socket.socket() as sock: sock.connect((server_addr, PORT)) with sock.makefile(mode='rwb') as fake_fil: send_pkt(fake_fil, version_pkt(client_addr, server_addr, nonce)) remote_ver = recv_pkt(fake_fil) print(f'nonce: {remote_ver.nNonce}') send_pkt(fake_fil, msg_verack()) i = 0 try: while True: if i == 3: g_getaddr_send_ts = time.time() print("sending getaddr!") send_pkt(fake_fil, msg_getaddr()) elif i == 5: print(f"sending inv for {b2lx(FAKE_TX_HASH)}!") pkt = msg_inv() inv = CInv() inv.type = 1 # TX inv.hash = FAKE_TX_HASH pkt.inv.append(inv) INV_SEND_TS = time.time() send_pkt(fake_fil, pkt) elif i == 4: print(f"sending marker ips") pkt = msg_addr() for fake_ip in gen_fake_ips(RUN_ID, 78, 0xf): addr = CAddress() addr.ip = fake_ip addr.port = 9 # discard addr.nTime = g_ver_ts addr.nServices = 1 # NODE_NETWORK, otherwise they won't always accept the addr pkt.addrs.append(addr) send_pkt(fake_fil, pkt) recv_pkt(fake_fil) i += 1 except KeyboardInterrupt: pass return remote_ver.nNonce
def test_serializationDiff(self): # Sanity check that the serialization code preserves differences c1 = CAddress() c1.ip = "1.1.1.1" c1.port = 8333 c1.nTime = 1420576401 c2 = CAddress() c2.ip = "1.1.1.2" c2.port = 8333 c2.nTime = 1420576401 self.assertNotEqual(c1, c2) c1Serialized = c1.serialize() c2Serialized = c2.serialize() self.assertNotEqual(c1Serialized, c2Serialized) c1Deserialized = CAddress.deserialize(c1Serialized) c2Deserialized = CAddress.deserialize(c2Serialized) self.assertNotEqual(c1Deserialized, c2Deserialized)
def test_serializationSimple(self): c = CAddress() cSerialized = c.serialize() cDeserialized = CAddress.deserialize(cSerialized) cSerializedTwice = cDeserialized.serialize() self.assertEqual(cSerialized, cSerializedTwice)
class msg_version(MsgSerializable): command = b"version" def __init__(self, protover=PROTO_VERSION): super(msg_version, self).__init__(protover) self.nVersion = protover self.nServices = 1 self.nTime = int(time.time()) self.addrTo = CAddress(PROTO_VERSION) self.addrFrom = CAddress(PROTO_VERSION) self.nNonce = random.getrandbits(64) self.strSubVer = b"/python-bitcoinlib:" + bitcoin.__version__.encode("ascii") + b"/" self.nStartingHeight = -1 @classmethod def msg_deser(cls, f, protover=PROTO_VERSION): c = cls() c.nVersion = struct.unpack(b"<i", ser_read(f, 4))[0] if c.nVersion == 10300: c.nVersion = 300 c.nServices = struct.unpack(b"<Q", ser_read(f, 8))[0] c.nTime = struct.unpack(b"<q", ser_read(f, 8))[0] c.addrTo = CAddress.stream_deserialize(f, True) if c.nVersion >= 106: c.addrFrom = CAddress.stream_deserialize(f, True) c.nNonce = struct.unpack(b"<Q", ser_read(f, 8))[0] c.strSubVer = VarStringSerializer.stream_deserialize(f) if c.nVersion >= 209: c.nStartingHeight = struct.unpack(b"<i", ser_read(f, 4))[0] else: c.nStartingHeight = None else: c.addrFrom = None c.nNonce = None c.strSubVer = None c.nStartingHeight = None return c def msg_ser(self, f): f.write(struct.pack(b"<i", self.nVersion)) f.write(struct.pack(b"<Q", self.nServices)) f.write(struct.pack(b"<q", self.nTime)) self.addrTo.stream_serialize(f, True) self.addrFrom.stream_serialize(f, True) f.write(struct.pack(b"<Q", self.nNonce)) VarStringSerializer.stream_serialize(self.strSubVer, f) f.write(struct.pack(b"<i", self.nStartingHeight)) def __repr__(self): return ( "msg_version(nVersion=%i nServices=%i nTime=%s addrTo=%s addrFrom=%s nNonce=0x%016X strSubVer=%s nStartingHeight=%i)" % ( self.nVersion, self.nServices, time.ctime(self.nTime), repr(self.addrTo), repr(self.addrFrom), self.nNonce, self.strSubVer, self.nStartingHeight, ) )
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))
def local_caddress(self): caddress = CAddress() caddress.nTime = self.connect_time caddress.ip = self.local_address.host caddress.port = self.local_address.port return caddress