Skip to content

Commit 599f414

Browse files
committed
v2.4.5: rune turbo decode fix (upstream magicoss/runestone-lib:src/runestone.ts:123)
Upstream Runestone.decipher reads `etching.turbo` from `etchingResult.set` inside a branch that's only entered when `etchingResult.set === true`, so every etching reports turbo=true regardless of the on-chain TURBO bit. Reference impl (ord, crates/ordinals/src/runestone.rs:86) takes turbo from `Flag::Turbo.take(&mut flags)`. Fix is one line in src/rune/src/runestone.ts -- read turboResult.set instead of etchingResult.set. Two real-mainnet regression tests in rune-parser.service.spec.ts under "Etching turbo flag", ground truth confirmed against ordinals.com via explorer.ordinalsbot.com/rune/<name>: Z*Z*Z*Z*Z*FEHU*Z*Z*Z*Z*Z (tx 2bb85f4b...) -> turbo=true DOG*GO*TO*THE*MOON (tx e7913408...) -> turbo=false Upstream PR filed: me-foundation/runestone-lib#83.
1 parent ffcd058 commit 599f414

4 files changed

Lines changed: 98 additions & 2 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ordpool-parser",
3-
"version": "2.4.4",
3+
"version": "2.4.5",
44
"description": "Zero-dependency TypeScript parser for Bitcoin digital artifacts: Inscriptions, Runes, BRC-20, SRC-20, CAT-21, Atomicals, Labitbu, OpenTimestamps. Works in Node.js and browsers.",
55
"repository": {
66
"type": "git",

src/rune/rune-parser.service.spec.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,4 +394,36 @@ describe('Rune parser', () => {
394394
const runestone = RuneParserService.parse(txn);
395395
expect(runestone).toBe(null);
396396
});
397+
398+
// ===========================================================================
399+
// Turbo flag — Flag::Turbo (bit 2) in the runestone Flags tag.
400+
//
401+
// The etcher opts into "all future protocol changes". Reference indexer:
402+
// crates/ordinals/src/runestone.rs:86 -- `turbo: Flag::Turbo.take(&mut flags)`.
403+
//
404+
// Two real mainnet etchings, ground truth confirmed against ordinals.com
405+
// (via explorer.ordinalsbot.com/rune/<name>):
406+
// Z•Z•Z•Z•Z•FEHU•Z•Z•Z•Z•Z -- turbo: true
407+
// DOG•GO•TO•THE•MOON -- turbo: false
408+
// ===========================================================================
409+
describe('Etching turbo flag', () => {
410+
411+
it('should set turbo=true for Z•Z•Z•Z•Z•FEHU•Z•Z•Z•Z•Z (TURBO bit set on chain)', () => {
412+
const txn = readTransaction('2bb85f4b004be6da54f766c17c1e855187327112c231ef2ff35ebad0ea67c69e');
413+
const runestone = RuneParserService.parse(txn);
414+
const etching = runestone?.runestone?.etching;
415+
416+
expect(etching?.runeName).toBe('Z•Z•Z•Z•Z•FEHU•Z•Z•Z•Z•Z');
417+
expect(etching?.turbo).toBe(true);
418+
});
419+
420+
it('should set turbo=false for DOG•GO•TO•THE•MOON (TURBO bit NOT set on chain)', () => {
421+
const txn = readTransaction('e79134080a83fe3e0e06ed6990c5a9b63b362313341745707a2bff7d788a1375');
422+
const runestone = RuneParserService.parse(txn);
423+
const etching = runestone?.runestone?.etching;
424+
425+
expect(etching?.runeName).toBe('DOG•GO•TO•THE•MOON');
426+
expect(etching?.turbo).toBe(false);
427+
});
428+
});
397429
});

src/rune/src/runestone.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,11 @@ export class Runestone {
121121
const premine = Tag.take(Tag.PREMINE, fields, 1, ([value]) => Some(value));
122122

123123
const turboResult = Flag.take(flags, Flag.TURBO);
124-
const turbo = etchingResult.set;
124+
// Upstream magicoss/runestone-lib bug (their runestone.ts:123) reads
125+
// `etchingResult.set` here, which is always true inside this lambda
126+
// -- so every etching wrongly reports turbo=true. ord's reference
127+
// does `turbo: Flag::Turbo.take(&mut flags)`. Use turboResult.set.
128+
const turbo = turboResult.set;
125129
flags = turboResult.flags;
126130

127131
return Some(new Etching(divisibility, rune, spacers, symbol, terms, premine, turbo));
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{
2+
"txid": "e79134080a83fe3e0e06ed6990c5a9b63b362313341745707a2bff7d788a1375",
3+
"version": 2,
4+
"locktime": 0,
5+
"vin": [
6+
{
7+
"txid": "fa6c1d39437cfe07d314bfbb0af87375359389dc07d2c13fe7670710d7cce86b",
8+
"vout": 0,
9+
"prevout": {
10+
"scriptpubkey": "51206b4e6bdab4fe34b45c4d396df812fc9759f6db25a4f14a0f724e17dfa3d8b0e7",
11+
"scriptpubkey_asm": "OP_PUSHNUM_1 OP_PUSHBYTES_32 6b4e6bdab4fe34b45c4d396df812fc9759f6db25a4f14a0f724e17dfa3d8b0e7",
12+
"scriptpubkey_type": "v1_p2tr",
13+
"scriptpubkey_address": "bc1pdd8xhk45lc6tghzd89klsyhujavldke95nc55rmjfctalg7ckrnsvgezx0",
14+
"value": 290783340
15+
},
16+
"scriptsig": "",
17+
"scriptsig_asm": "",
18+
"witness": [
19+
"e21839ce81dcd45e1e6b04df0e6c44d719134a5313da81c2f0fabb5bf46fbc26ab4b1c5110e001c862f496462cad5694a34eaf3478bde460ae9c982ff87820fa",
20+
"20658204e3f80250f45924140b103ea13c6ae9e3186f49af92027453a6fa7b1113ac0063036f7264010b205f83846783d4a3a733b68c4f5e77fd4d421c7a18417856c76695e1234efb8f61010200010d0887d0100e5cdff79d68",
21+
"c0658204e3f80250f45924140b103ea13c6ae9e3186f49af92027453a6fa7b1113"
22+
],
23+
"is_coinbase": false,
24+
"sequence": 5,
25+
"inner_witnessscript_asm": "OP_PUSHBYTES_32 658204e3f80250f45924140b103ea13c6ae9e3186f49af92027453a6fa7b1113 OP_CHECKSIG OP_0 OP_IF OP_PUSHBYTES_3 6f7264 OP_PUSHBYTES_1 0b OP_PUSHBYTES_32 5f83846783d4a3a733b68c4f5e77fd4d421c7a18417856c76695e1234efb8f61 OP_PUSHBYTES_1 02 OP_0 OP_PUSHBYTES_1 0d OP_PUSHBYTES_8 87d0100e5cdff79d OP_ENDIF"
26+
}
27+
],
28+
"vout": [
29+
{
30+
"scriptpubkey": "512059bb8e559e5c0f2688ba1f157e4ca2076625bec23d02db529523c7371754ce94",
31+
"scriptpubkey_asm": "OP_PUSHNUM_1 OP_PUSHBYTES_32 59bb8e559e5c0f2688ba1f157e4ca2076625bec23d02db529523c7371754ce94",
32+
"scriptpubkey_type": "v1_p2tr",
33+
"scriptpubkey_address": "bc1ptxacu4v7ts8jdz96ru2hun9zqanzt0kz85pdk554y0rnw965e62qu47srz",
34+
"value": 330
35+
},
36+
{
37+
"scriptpubkey": "5120191f3cbc89a06c804202d917b05822857a9fdc675a42b1160468077364c8e4b0",
38+
"scriptpubkey_asm": "OP_PUSHNUM_1 OP_PUSHBYTES_32 191f3cbc89a06c804202d917b05822857a9fdc675a42b1160468077364c8e4b0",
39+
"scriptpubkey_type": "v1_p2tr",
40+
"scriptpubkey_address": "bc1pry0ne0yf5pkgqsszmytmqkpzs4aflhr8tfptz9sydqrhxexgujcqqler2t",
41+
"value": 10000
42+
},
43+
{
44+
"scriptpubkey": "6a5d2102010487a1c3f0c0ebf7fb9d01010503d4040595e80706808084fea6dee1111601",
45+
"scriptpubkey_asm": "OP_RETURN OP_PUSHNUM_13 OP_PUSHBYTES_33 02010487a1c3f0c0ebf7fb9d01010503d4040595e80706808084fea6dee1111601",
46+
"scriptpubkey_type": "op_return",
47+
"value": 0
48+
}
49+
],
50+
"size": 375,
51+
"weight": 921,
52+
"sigops": 0,
53+
"fee": 290773010,
54+
"status": {
55+
"confirmed": true,
56+
"block_height": 840000,
57+
"block_hash": "0000000000000000000320283a032748cef8227873ff4872689bf23f1cda83a5",
58+
"block_time": 1713571767
59+
}
60+
}

0 commit comments

Comments
 (0)