메시지 하나의 세 가지 해시

TON 메시지는 bag of cells, 즉 BoC로 이동하며, 누가 말하느냐에 따라 세 가지 다른 해시가 "메시지 해시"라고 불립니다. TONNode 멤풀 스트림은 모든 대기 메시지에 대해 다음 이름으로 세 가지를 모두 전달합니다.

  • cell_hash — 루트 셀의 표현 해시입니다. 익스플로러가 메시지 해시라고 부르는 것이며, 메시지가 블록에 포함되면 그 트랜잭션의 in_msg 해시와 같습니다. 셀이 바이트로 어떻게 직렬화되었는지가 아니라 셀 자체에만 의존합니다.
  • norm_hash — TEP-467 정규화 해시입니다. 같은 외부 수신 메시지를 고정된 형태(ext_in_msg_info$10 src:addr_none dest:<unchanged> import_fee:0 init:nothing body:right$1 ^body)로 다시 쓴 것의 해시입니다. 메시지가 다시 직렬화되거나 src, import_fee, init 필드가 바뀌어도 그대로 유지됩니다. 메시지가 이미 그 형태라면 norm_hash는 cell_hash와 같습니다.
  • sha256 — 전달된 그대로의 BoC 바이트에 대한 SHA-256입니다. 같은 셀이라도 여러 유효한 방식(인덱스 유무, CRC32C 유무)으로 직렬화될 수 있고, 각 직렬화는 서로 다른 SHA-256을 가지지만 두 셀 해시는 변하지 않습니다.

API마다 다르기 때문에 도구는 각각을 hex와 base64로 출력합니다. 익스플로러와 liteserver 프로토콜은 hex를 쓰고, 여러 HTTP API는 base64를 반환합니다.

정규화 해시가 존재하는 이유

외부 메시지는 지갑이 서명하고, 릴레이하는 누군가가 네트워크에 전달합니다. 도중에 다시 인코딩될 수 있고, 릴레이어가 src 주소, import_fee, 첨부된 init을 추가하거나 제거할 수 있는데, 이 중 어느 것도 지갑이 서명한 것이 아닙니다. 각 변경은 새 루트 셀과 새 cell_hash를 만들기 때문에, 셀 해시로 중복을 제거하는 노드는 같은 서명된 페이로드를 여러 번 받아들이게 됩니다. TEP-467은 해시되는 형태를 고정하여 이런 변형이 모두 하나의 정체성으로 모이게 하며, 노드 자체의 get_ext_in_msg_hash_norm(validator/impl/external-message.cpp)이 그렇게 계산합니다.

구성은 단순합니다. 대상 비트를 그대로 취하고, 출처를 0으로, 수수료를 0으로 하고, init을 버리고, 본문이 원래 참조에 있었든 아니든 참조에 넣습니다. 정규화 해시는 외부 수신 메시지에만 있으며, 내부 메시지나 외부 발신 메시지에 대해서는 도구가 나머지 둘을 보여주고 그렇다고 알려줍니다.

멤풀 스트림이 전달하는 것

TONNode 멤풀 스트림의 각 msg 프레임은 boc 자체, 그 size, 그리고 위에서 정의한 cell_hash, norm_hash, sha256을 전달합니다. 자신의 처리에서는 cell_hash로 중복을 제거하세요. 같은 메시지가 처음에는 early(미검증)로, 그다음 checked로 두 번 도착할 수 있고, 재연결 후 다시 올 수도 있습니다. sha256은 노드가 받은 바이트의 중복 제거에 쓰는 키이므로, 다시 인코딩한 것이 아니라 전달된 바이트에 대해 해시됩니다.

실제 메시지로 테스트됨

여기의 구현은 스트림 자체의 파서와 정확히 같은 방식으로 정규화 셀을 만들며, 저장소의 테스트 스위트는 72개의 실제 메인넷 외부 메시지(스트림의 픽스처 세트로, 각각 스트림이 전달한 cell_hash, norm_hash, sha256을 가짐)를 통과시키고 세 값이 모두 일치하는지 단언합니다. 멤풀 문서의 예시 메시지도 그중 하나입니다. 붙여 넣으면 세 값을 나란히 볼 수 있습니다.