Skip to content

fix(mempool): use dyn-encoded Branch for PendingOperationsListWithError in TallinN#17

Merged
GImbrailo merged 1 commit intov2from
fix/tallinn-pending-ops-dyn-branch
Mar 16, 2026
Merged

fix(mempool): use dyn-encoded Branch for PendingOperationsListWithError in TallinN#17
GImbrailo merged 1 commit intov2from
fix/tallinn-pending-ops-dyn-branch

Conversation

@GImbrailo
Copy link
Copy Markdown
Contributor

Problem

TallinN (proto_024 PtTALLiNtPec7mE7yY4m3k26J8Qukef3E3ehzhfXgFZKGtDdAXu) changed the wire encoding for refused, outdated, branch_refused, and branch_delayed operations: the Branch field is now dyn-prefixed (4-byte big-endian uint32 length 0x00000020 = 32, then 32 bytes) instead of the raw 32-byte encoding used in earlier protocols.

validated ops still use raw 32-byte Branch — only the error bucket types changed.

Impact

PendingOperationsListWithError embeds PendingOperationsList which uses raw Branch. When decoding TallinN refused/outdated ops:

  1. The 4-byte dyn prefix 0x00000020 is read as the last 4 bytes of the Branch hash
  2. The next 4 bytes of the actual Branch bytes get interpreted as the Contents dyn length
  3. Those bytes produce enormous values (e.g. 3,681,343,224) → "buffer is too short, at least 3681343224 byte(s) were expected"

The sidecar doesn't crash — ops that fail to parse are skipped — but mempool counts are under-reported for all non-validated operations.

Fix

Inline the fields from PendingOperationsList into PendingOperationsListWithError and add tz:"dyn" to the Branch field.

PendingOperationsList itself is unchanged — validated ops still use raw Branch encoding.

UnprocessedPendingOperationsList already has tz:"dyn" on Branch and is unaffected.

Verification

  • go test ./... passes, including clientv2/mempool and proto_024_PtTALLiN
  • Root cause confirmed by binary inspection of live TallinN shadownet mempool responses: all refused/outdated ops have 0x00000020 at offset 0 of the Branch field; validated ops use raw 32-byte Branch

TallinN (proto_024) changed the wire encoding for refused, outdated,
branch_refused, and branch_delayed operations to use a dyn-prefixed
Branch field (4-byte big-endian uint32 length + 32 bytes) instead of
the raw 32-byte Branch used by validated ops.

PendingOperationsListWithError was embedding PendingOperationsList which
uses raw Branch encoding, causing the 4-byte dyn prefix to be
misinterpreted as part of the Branch hash. The subsequent 4 bytes were
then read as the Contents dyn length, producing enormous values like
3,681,343,224 and the "buffer is too short" error.

Fix by inlining the fields from PendingOperationsList and adding
tz:"dyn" to the Branch field. PendingOperationsList itself is unchanged
since validated ops still use raw Branch encoding.

UnprocessedPendingOperationsList already had tz:"dyn" on Branch and is
unaffected.
Copy link
Copy Markdown
Collaborator

@chunkitmax chunkitmax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@GImbrailo GImbrailo merged commit c6181a5 into v2 Mar 16, 2026
1 check passed
@GImbrailo GImbrailo deleted the fix/tallinn-pending-ops-dyn-branch branch March 16, 2026 21:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants