diff --git a/parser/db.py b/parser/db.py index daee31f..cba9b41 100644 --- a/parser/db.py +++ b/parser/db.py @@ -139,6 +139,26 @@ def get_parent_message_body(self, msg_hash) -> str: if not res: return None return res['body_boc'] + + """ + Returns True if parent message exists (i.e there is an internal message A which triggered a transactions T resulted in sending the current message M: ...A->T->M) + or False if the current message is the first messages in the transaction chain initiated by external message: ext->T->M + or throws an exception if trace_edges table does not contain the message + """ + def parent_message_exists(self, msg_hash) -> bool: + assert self.conn is not None + with self.conn.cursor(cursor_factory=RealDictCursor) as cursor: + cursor.execute( + """ + select trace_id, left_tx from trace_edges te + where te.msg_hash = %s + """, + (msg_hash, ), + ) + res = cursor.fetchone() + if not res: + raise Exception(f"trace_edges table does not contain the message {msg_hash}") + return res['trace_id'] != res['left_tx'] """ Returns parent message with message body diff --git a/parser/parsers/message/jetton_mint.py b/parser/parsers/message/jetton_mint.py index 84c8a74..a66be15 100644 --- a/parser/parsers/message/jetton_mint.py +++ b/parser/parsers/message/jetton_mint.py @@ -29,7 +29,7 @@ def topics(self): return [TOPIC_MESSAGES] def predicate(self, obj: dict) -> bool: - return obj.get("opcode") == Parser.opcode_signed(0x178d4519) and obj.get("direction") == "in" + return obj.get("opcode") == Parser.opcode_signed(0x178d4519) and obj.get("direction") == "in" and obj.get("source") def handle_internal(self, obj: dict, db: DB): # ensure we have no transfer operation before @@ -37,6 +37,9 @@ def handle_internal(self, obj: dict, db: DB): if prev_message and prev_message.get("opcode") == Parser.opcode_signed(0x0f8a7ea5): # skip ordinary chain transfer => internal_transfer return + if not prev_message: + if db.parent_message_exists(obj.get("msg_hash")): + raise Exception(f"trace_edges table contains a parent messages but get_parent_message_with_body returned None") logger.info(f"Parsing jetton mint message {Parser.require(obj.get('msg_hash'))}") cell = Parser.message_body(obj, db).begin_parse()