Skip to content

Correctly parse inscriptions when using minimal opcodes#1769

Closed
arik-so wants to merge 9 commits intoordinals:masterfrom
arik-so:handle-opcode-tags
Closed

Correctly parse inscriptions when using minimal opcodes#1769
arik-so wants to merge 9 commits intoordinals:masterfrom
arik-so:handle-opcode-tags

Conversation

@arik-so
Copy link
Copy Markdown
Contributor

@arik-so arik-so commented Feb 16, 2023

Currently, minimal opcodes like OP_1 and OP_2 don't get recognized because all opcode operations that aren't OP_ENDIF result in an invalid inscription error, necessitating that all numeric opcodes be pushed as slices instead. However, that is in violation of BIP 62 motivation §3.

@tyjvazum
Copy link
Copy Markdown

@arik-so, could you provide a short description of the logic used in your changes?

@arik-so
Copy link
Copy Markdown
Contributor Author

arik-so commented Feb 17, 2023

Certainly! In the code, or as a comment on the PR?

The point is basically that the documentation suggests using OP_1, OP_2, etc. for the various content property tags. However, the way it's currently being handled, OP_1 would not actually be recognized, because it would match the Instruction::Op arm. The issue is that rust-bitcoin's push_slice does not do minimal opcode detection, so pushing &[1] actually results in the hex encoding of 0101 instead of the opcode hex encoding 51 (81 in decimal). The actual opcode would be interpreted as invalid.

The set of numeric opcodes ranges from 1-16 (it just so happens that OP_0 and OP_FALSE and the 0-byte-slice are all encoded identically as (00), so that does not cause any breakages.

@tyjvazum
Copy link
Copy Markdown

Thank you for the detailed, clear explanation. I don't think code comments are necessary. However, I do have a couple other questions: what's the logic for using Vec instead of u8, and shouldn't this same change be made (for building as well as parsing) in the append_reveal_script_to_builder function, which currently uses push_slice?

@arik-so
Copy link
Copy Markdown
Contributor Author

arik-so commented Feb 17, 2023

To answer your first question, the reason I had to make it a Vec instead of a slice is that in the ::Op case, I'm instantiating a new vector, and so merely using a reference would result in the vector getting dropped with the closure of the match arm, a problem which the match arm that receives a reference to a vec with a longer lifetime doesn't have.

Regarding your other question, I don't think append_reveal_script_to_builder should be modified yet, because people running older versions of ord would then not see inscriptions generated after this change gets merged. I think that change should happen in due time, maybe a couple weeks or a month after the parsing becomes more permissive. Or perhaps even sooner if the software updates propagate more quickly.

@shesek
Copy link
Copy Markdown

shesek commented Feb 20, 2023

Couldn't this be solved by using Builder::push_int() instead of Builder::push_slice() for pushing the tags and Script::instructions_minimal() instead of Script::instructions()?

@arik-so
Copy link
Copy Markdown
Contributor Author

arik-so commented Feb 20, 2023

That would fix the script construction, but not its parsing. As I pointed out in my previous comment, the construction should not be modified until the parsing fix propagates to most ord clients such that the inscriptions don't break.

It's a followup PR that I hope to make in a couple weeks or so, if/when this one gets merged.

@shesek
Copy link
Copy Markdown

shesek commented Feb 20, 2023

Why won't instructions_minimal() fix parsing?

@arik-so
Copy link
Copy Markdown
Contributor Author

arik-so commented Feb 20, 2023

Sorry, instructions_minimal would improve parsing (though it obviously still requires the ::Ops change), but I strongly believe that the parsing fix should go out several weeks prior to the inscription change. I think though that even with instructions_minimal, the slice match arm of the parser would remain necessary for any tags above 16.

@brandonblack
Copy link
Copy Markdown

Ping! Relaxing this parsing in ord seems important for future interoperability, even though it will renumber inscriptions.

@arik-so
Copy link
Copy Markdown
Contributor Author

arik-so commented May 24, 2023

Any chance CI might be permitted to run on this PR?

@tyjvazum
Copy link
Copy Markdown

@arik-so, I'm working on arb. Any improvements you have in mind would be very welcome 👍

@veryordinally
Copy link
Copy Markdown
Collaborator

Any chance CI might be permitted to run on this PR?

@arik-so if you could update this PR we'll run CI. We'd like to integrate this for completing the cursed inscriptions handling.

@arik-so arik-so force-pushed the handle-opcode-tags branch 2 times, most recently from afa3a5f to af6508a Compare July 10, 2023 11:22
Copy link
Copy Markdown
Collaborator

@veryordinally veryordinally left a comment

Choose a reason for hiding this comment

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

The code to recognize and parse the inscriptions with minimal opcodes looks good to me.

We would need to make these inscriptions cursed, however, as otherwise existing inscription numbers will change. So we need a new type of curse, and then need to percolate a cursed status up from where we handle the minimal opcodes.

A full test would entail comparing an index generated with this PR with a previous index and verifying that all positive inscription numbers remain unchanged (index can be exported with index export into an easily comparable format).

Let me know if you feel like this is something you'd be up to doing, or if I should add it to my backlog.

@arik-so
Copy link
Copy Markdown
Contributor Author

arik-so commented Jul 10, 2023

Probably not until this upcoming weekend. If you have pointers towards similar unit tests though, they'd be greatly appreciated! Thanks!

@veryordinally
Copy link
Copy Markdown
Collaborator

Probably not until this upcoming weekend. If you have pointers towards similar unit tests though, they'd be greatly appreciated! Thanks!

This would be a test on the full mainnet chain so outside our unit test and integration test framework. I also won't get to this before the weekend, happy to collaborate on this then.

@arik-so
Copy link
Copy Markdown
Contributor Author

arik-so commented Jul 18, 2023

@veryordinally I added cursing to the inscription, but no external curse verification yet.

@arik-so arik-so force-pushed the handle-opcode-tags branch from 42326b3 to a477f1d Compare July 18, 2023 13:47
@arik-so arik-so force-pushed the handle-opcode-tags branch from a477f1d to 5abaf55 Compare July 18, 2023 13:48
Copy link
Copy Markdown
Collaborator

@veryordinally veryordinally left a comment

Choose a reason for hiding this comment

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

Looks good - will format and resolve conflicts, then verify inscription number correctness.

@veryordinally
Copy link
Copy Markdown
Collaborator

@arik-so Sorry this took me a while to get to. Reviewed the cursed changes, looks good so far. I fixed the formatting so our CI is happy, but noticed your two tests are failing. Could you look into that?

@veryordinally
Copy link
Copy Markdown
Collaborator

@arik-so Looked like the tests weren't updated for the cursed logic - please check if my changes make sense. Will now run inscription number validation, which will take a day or so.

@arik-so
Copy link
Copy Markdown
Contributor Author

arik-so commented Aug 8, 2023

You are right, they weren't. I didn't make the cursing boolean setting public in the constructor, so the tests for verifying the newly created inscriptions had mismatched internal values for the structs, and time got away from me so I never got around to fixing that. Taking a look at your changes now, thanks!

@arik-so
Copy link
Copy Markdown
Contributor Author

arik-so commented Aug 8, 2023

Your tests look great. I am personally still not super happy about the uses_minimal_opcodes field just hanging out at the top level of the Inscription struct, but I felt like nesting it deeper would result in even more technical debt down the line, though who knows.

@veryordinally
Copy link
Copy Markdown
Collaborator

See also #1403

@arik-so
Copy link
Copy Markdown
Contributor Author

arik-so commented Aug 13, 2023

Sorry, been very busy. Will look into the performance penalty issue.

@arik-so
Copy link
Copy Markdown
Contributor Author

arik-so commented Aug 29, 2023

Hey @veryordinally, I have modified the pattern matching to only match on the positive push num operators. I suspect having to run op_code.to_u8() on every single op code may have been a contributing factor to the slowdown.

@raphjaph
Copy link
Copy Markdown
Collaborator

raphjaph commented Oct 8, 2023

We merged this: #2497

@casey casey closed this Oct 25, 2023
hans-crypto added a commit to ordpool-space/ordpool-parser that referenced this pull request Sep 12, 2024
see #2
see ordinals/ord#1403 (Use minimal data-pushes)
see ordinals/ord#2505 (Make docs more precise)
see ordinals/ord#1769 (Correctly parse inscriptions when using minimal opcodes)
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.

7 participants