Changeset View
Changeset View
Standalone View
Standalone View
test/functional/test_framework/mininode.py
Show First 20 Lines • Show All 201 Lines • ▼ Show 20 Lines | def _on_data(self): | ||||
if self.recvbuf[:4] != self.magic_bytes: | if self.recvbuf[:4] != self.magic_bytes: | ||||
raise ValueError( | raise ValueError( | ||||
"magic bytes mismatch: {} != {}".format( | "magic bytes mismatch: {} != {}".format( | ||||
repr( | repr( | ||||
self.magic_bytes), repr( | self.magic_bytes), repr( | ||||
self.recvbuf))) | self.recvbuf))) | ||||
if len(self.recvbuf) < 4 + 12 + 4 + 4: | if len(self.recvbuf) < 4 + 12 + 4 + 4: | ||||
return None | return None | ||||
command = self.recvbuf[4:4 + 12].split(b"\x00", 1)[0] | msgtype = self.recvbuf[4:4 + 12].split(b"\x00", 1)[0] | ||||
msglen = struct.unpack( | msglen = struct.unpack( | ||||
"<i", self.recvbuf[4 + 12:4 + 12 + 4])[0] | "<i", self.recvbuf[4 + 12:4 + 12 + 4])[0] | ||||
checksum = self.recvbuf[4 + 12 + 4:4 + 12 + 4 + 4] | checksum = self.recvbuf[4 + 12 + 4:4 + 12 + 4 + 4] | ||||
if len(self.recvbuf) < 4 + 12 + 4 + 4 + msglen: | if len(self.recvbuf) < 4 + 12 + 4 + 4 + msglen: | ||||
return None | return None | ||||
msg = self.recvbuf[4 + 12 + 4 + 4:4 + 12 + 4 + 4 + msglen] | msg = self.recvbuf[4 + 12 + 4 + 4:4 + 12 + 4 + 4 + msglen] | ||||
h = sha256(sha256(msg)) | h = sha256(sha256(msg)) | ||||
if checksum != h[:4]: | if checksum != h[:4]: | ||||
raise ValueError("got bad checksum " + repr(self.recvbuf)) | raise ValueError("got bad checksum " + repr(self.recvbuf)) | ||||
self.recvbuf = self.recvbuf[4 + 12 + 4 + 4 + msglen:] | self.recvbuf = self.recvbuf[4 + 12 + 4 + 4 + msglen:] | ||||
if command not in MESSAGEMAP: | if msgtype not in MESSAGEMAP: | ||||
raise ValueError("Received unknown command from {}:{}: '{}' {}".format( | raise ValueError("Received unknown msgtype from {}:{}: '{}' {}".format( | ||||
self.dstaddr, self.dstport, command, repr(msg))) | self.dstaddr, self.dstport, msgtype, repr(msg))) | ||||
f = BytesIO(msg) | f = BytesIO(msg) | ||||
m = MESSAGEMAP[command]() | m = MESSAGEMAP[msgtype]() | ||||
m.deserialize(f) | m.deserialize(f) | ||||
self._log_message("receive", m) | self._log_message("receive", m) | ||||
return m | return m | ||||
except Exception as e: | except Exception as e: | ||||
logger.exception('Error reading message:', repr(e)) | logger.exception('Error reading message:', repr(e)) | ||||
raise | raise | ||||
def on_message(self, message): | def on_message(self, message): | ||||
Show All 28 Lines | def send_raw_message(self, raw_message_bytes): | ||||
return | return | ||||
self._transport.write(raw_message_bytes) | self._transport.write(raw_message_bytes) | ||||
NetworkThread.network_event_loop.call_soon_threadsafe(maybe_write) | NetworkThread.network_event_loop.call_soon_threadsafe(maybe_write) | ||||
# Class utility methods | # Class utility methods | ||||
def build_message(self, message): | def build_message(self, message): | ||||
"""Build a serialized P2P message""" | """Build a serialized P2P message""" | ||||
command = message.command | msgtype = message.msgtype | ||||
data = message.serialize() | data = message.serialize() | ||||
tmsg = self.magic_bytes | tmsg = self.magic_bytes | ||||
tmsg += command | tmsg += msgtype | ||||
tmsg += b"\x00" * (12 - len(command)) | tmsg += b"\x00" * (12 - len(msgtype)) | ||||
tmsg += struct.pack("<I", len(data)) | tmsg += struct.pack("<I", len(data)) | ||||
th = sha256(data) | th = sha256(data) | ||||
h = sha256(th) | h = sha256(th) | ||||
tmsg += h[:4] | tmsg += h[:4] | ||||
tmsg += data | tmsg += data | ||||
return tmsg | return tmsg | ||||
def _log_message(self, direction, msg): | def _log_message(self, direction, msg): | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | class P2PInterface(P2PConnection): | ||||
def on_message(self, message): | def on_message(self, message): | ||||
"""Receive message and dispatch message to appropriate callback. | """Receive message and dispatch message to appropriate callback. | ||||
We keep a count of how many of each message type has been received | We keep a count of how many of each message type has been received | ||||
and the most recent message of each type.""" | and the most recent message of each type.""" | ||||
with mininode_lock: | with mininode_lock: | ||||
try: | try: | ||||
command = message.command.decode('ascii') | msgtype = message.msgtype.decode('ascii') | ||||
self.message_count[command] += 1 | self.message_count[msgtype] += 1 | ||||
self.last_message[command] = message | self.last_message[msgtype] = message | ||||
getattr(self, 'on_' + command)(message) | getattr(self, 'on_' + msgtype)(message) | ||||
except Exception: | except Exception: | ||||
print("ERROR delivering {} ({})".format( | print("ERROR delivering {} ({})".format( | ||||
repr(message), sys.exc_info()[0])) | repr(message), sys.exc_info()[0])) | ||||
raise | raise | ||||
# Callback methods. Can be overridden by subclasses in individual test | # Callback methods. Can be overridden by subclasses in individual test | ||||
# cases to provide custom message handling behaviour. | # cases to provide custom message handling behaviour. | ||||
▲ Show 20 Lines • Show All 367 Lines • Show Last 20 Lines |