Skip to content

Name the reason ASM output is refused for data after OP_RETURN too - #6

Merged
codenlighten merged 1 commit into
mainfrom
asm-refusal-reason
Sep 17, 2026
Merged

codenlighten merged 1 commit into
mainfrom
asm-refusal-reason

Conversation

@codenlighten

Copy link
Copy Markdown
Owner

Found while checking 0.1.2 from the registry. The refusal is correct, but its message was not:

$ echo 76756a4c03aabbcc > odd.hex && scriptmin --asm -o odd.asm odd.hex
scriptmin: cannot write this script as ASM: its ASM reads back as a different script; write it as hex

Cause

exactAsm found the reason from parsed ops. There the data after a top-level OP_RETURN is one opaque op, so a non-minimal push or an unnamed opcode inside it fell through to the generic message. The old check also compared each push with scriptmin's minimal push. That treats 01 05 as non-minimal, although ASM writes it as 05 and reads it back exactly.

Change

asmObstacles(buf) walks the bytes the way ASM reads them and reports:

  • a truncated push;
  • a push whose opcode is not the shortest for its length (OP_PUSHDATA1 for under 76 bytes, or an empty OP_PUSHDATA*);
  • an unnamed opcode.

The message comes from those. Only the message changes: whether a script is refused is still decided by reading its ASM back.

script before now
6a4c03aabbcc reads back as a different script not minimally encoded
516a4c00 reads back as a different script not minimally encoded
516a05aabb truncated push truncated push
516a0105 written: OP_1 OP_RETURN 05 same

Tests

  • The CLI test now expects the not minimally encoded reason for 76756a4c03aabbcc.
  • New assertion: 516a4c00 is refused with that reason.
  • npm test: 28/28.

The reason was found from parsed ops, where the data after a top-level
OP_RETURN is one opaque op, so a non-minimal push or an unnamed opcode there
was reported as 'its ASM reads back as a different script'. The script is now
walked byte by byte, the way ASM reads it: a push is non-minimal when its
opcode is not the shortest for its length (ASM records only the data).
@codenlighten

Copy link
Copy Markdown
Owner Author

Reviewed and checked with bsv 9.11.2:

  • Tests: 28/28 pass, and the PR adds no lint findings.
  • Fuzz: 6,000 generated scripts, with pushes of every encoding before and after OP_RETURN, unnamed opcodes, and truncated tails. Each refusal's reason was checked against a transcription of the node's GetScriptOp, not against scriptmin's own byte walk:
    • This branch: 2,477 accepted, all reading back exactly; 2,024 truncated, 530 not minimal and 969 data-only, every reason true.
    • main: the same 2,477 accepted, but 11 refusals (e.g. ac6a4c00) got the generic "reads back as a different script".

So only the message changed, as described. The accept/refuse decision is identical.

@codenlighten
codenlighten merged commit 46e0e31 into main Sep 17, 2026
5 checks passed
@codenlighten
codenlighten deleted the asm-refusal-reason branch September 17, 2026 16:42
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.

1 participant