ordinals / ord

👁‍🗨 Rare and exotic sats
https://ordinals.com
Creative Commons Zero v1.0 Universal
3.85k stars 1.38k forks source link

Cenotaph on empty payload or integer buffer. #4034

Closed dcorral closed 3 weeks ago

dcorral commented 3 weeks ago

acording to the "specification":

If a LEB128 varint contains more than 18 bytes, would overflow a u128, or is truncated, meaning that the end of the payload buffer is reached before encountering a byte with the continuation bit not set, the decoded runestone is a cenotaph with no etching, mint, or edicts.

In the function integers however an empty vector can be returned as Ok() leading to a valid rune with no data on it: https://github.com/ordinals/ord/blob/cb4a74576c028fe46ae905a6b0e867a620890fd4/crates/ordinals/src/runestone.rs#L236-L247 https://github.com/ordinals/ord/blob/cb4a74576c028fe46ae905a6b0e867a620890fd4/crates/ordinals/src/runestone.rs#L37-L42

This comes after an empty payload is treated as a valid payload: https://github.com/ordinals/ord/blob/cb4a74576c028fe46ae905a6b0e867a620890fd4/crates/ordinals/src/runestone.rs#L197-L234 https://github.com/ordinals/ord/blob/cb4a74576c028fe46ae905a6b0e867a620890fd4/crates/ordinals/src/runestone.rs#L15-L19

Shouldn't an empty payload be treated as a cenotaph as well?

Update: I can see there is a test that allows empty runestones but whats the use of an empty runestone?

https://github.com/ordinals/ord/blob/cb4a74576c028fe46ae905a6b0e867a620890fd4/crates/ordinals/src/runestone.rs#L485-L503

casey commented 3 weeks ago

A varint is indeed malformed if it is truncated. However, an empty payload does not contain a trunacted varint, since it does not contain any varints.

Shouldn't an empty payload be treated as a cenotaph as well?

Update: I can see there is a test that allows empty runestones but whats the use of an empty runestone?

An empty payload is useless but valid. We could have treated it as a cenotaph, but I'm not sure if that would be useful. You could imagine someone writing a function like this:

fn build_runestone(edicts: &[Edict]) -> Runestone {
  …
}

They would have to check if edicts was empty, otherwise they would risk producing a cenotaph, so it seems easier to just allow empty runestones.