Skip to content

Commit

Permalink
Document allowed opcodes in runestones (#3461)
Browse files Browse the repository at this point in the history
Document that data push opcodes 0 through 78 inclusive are allowed in
runestones, and opcodes 79 and above will produce a cenotaph. Also add a test
that makes sure that this is actually true.
  • Loading branch information
casey committed Apr 11, 2024
1 parent b5b7bbe commit 2cc14fd
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 3 deletions.
79 changes: 79 additions & 0 deletions crates/ordinals/src/runestone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2104,4 +2104,83 @@ mod tests {
}),
);
}

#[test]
fn all_pushdata_opcodes_are_valid() {
for i in 0..79 {
let mut script_pubkey = Vec::new();

script_pubkey.push(opcodes::all::OP_RETURN.to_u8());
script_pubkey.push(Runestone::MAGIC_NUMBER.to_u8());
script_pubkey.push(i);

match i {
0..=75 => {
for j in 0..i {
script_pubkey.push(if j % 2 == 0 { 1 } else { 0 });
}

if i % 2 == 1 {
script_pubkey.push(1);
script_pubkey.push(1);
}
}
76 => {
script_pubkey.push(0);
}
77 => {
script_pubkey.push(0);
script_pubkey.push(0);
}
78 => {
script_pubkey.push(0);
script_pubkey.push(0);
script_pubkey.push(0);
script_pubkey.push(0);
}
_ => unreachable!(),
}

assert_eq!(
Runestone::decipher(&Transaction {
version: 2,
lock_time: LockTime::ZERO,
input: default(),
output: vec![TxOut {
script_pubkey: script_pubkey.into(),
value: 0,
},],
})
.unwrap(),
Artifact::Runestone(Runestone::default()),
);
}
}

#[test]
fn all_non_pushdata_opcodes_are_invalid() {
for i in 79..=u8::MAX {
assert_eq!(
Runestone::decipher(&Transaction {
version: 2,
lock_time: LockTime::ZERO,
input: default(),
output: vec![TxOut {
script_pubkey: vec![
opcodes::all::OP_RETURN.to_u8(),
Runestone::MAGIC_NUMBER.to_u8(),
i
]
.into(),
value: 0,
},],
})
.unwrap(),
Artifact::Cenotaph(Cenotaph {
flaws: Flaw::Opcode.into(),
..default()
}),
);
}
}
}
9 changes: 6 additions & 3 deletions docs/src/runes/specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,12 @@ OP_13`. If deciphering fails, later matching outputs are not considered.

#### Assembling the Payload Buffer

The payload buffer is assembled by concatenating data pushes. If a non-data
push opcode is encountered, the deciphered runestone is a cenotaph with no
etching, mint, or edicts.
The payload buffer is assembled by concatenating data pushes, after `OP_13`, in
the matching script pubkey.

Data pushes are opcodes 0 through 78 inclusive. If a non-data push opcode is
encountered, i.e., any opcode equal to or greater than opcode 79, the
deciphered runestone is a cenotaph with no etching, mint, or edicts.

#### Decoding the Integer Sequence

Expand Down

0 comments on commit 2cc14fd

Please sign in to comment.