Skip to content

Commit 4e7bdc6

Browse files
author
Ludo Galabru
authored
Merge pull request #246 from hirosystems/fix/jubilee-indexing
fix: replay + jubilee number increment
2 parents 9458956 + d5bf88f commit 4e7bdc6

File tree

3 files changed

+42
-39
lines changed

3 files changed

+42
-39
lines changed

Diff for: README.md

+17-14
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
2-
/ / ▶ Ordhook
1+
/ / ▶ Ordhook
32
/ --- / Ordinal indexing engine based on Chainhook.
43
/ / Build indexes, standards and protocols on top of Ordinals and Inscriptions (BRC20, etc).
5-
4+
65

76
                                   [![Introduction](https://img.shields.io/badge/%23-%20Introduction%20-orange?labelColor=gray)](#Introduction)
87
    [![Features](https://img.shields.io/badge/%23-Features-orange?labelColor=gray)](#Features)
98
    [![Getting started](https://img.shields.io/badge/%23-Quick%20Start-orange?labelColor=gray)](#Quick-start)
109
    [![Documentation](https://img.shields.io/badge/%23-Documentation-orange?labelColor=gray)](#Documentation)
1110
    [![Contribute](https://img.shields.io/badge/%23-Contribute-orange?labelColor=gray)](#Contribute)
1211

13-
***
12+
---
1413

1514
# Introduction
1615

@@ -22,13 +21,13 @@ The **ordhook** is an indexer designed to help developers build new re-org-resis
2221

2322
The **ordhook** uses [Chainhook SDK](https://github.com/hirosystems/chainhook/tree/develop/components/chainhook-sdk) from the [Chainhook](https://github.com/hirosystems/chainhook/tree/develop) project, which is a re-org-aware transaction indexing engine for Stacks and Bitcoin. The SDK is designed with first-class event-driven principles, so it helps developers extract transactions from blocks efficiently and keeps a consistent view of the chain state.
2423

25-
With **ordhook**, Bitcoin developers can reliably implement feature-rich protocols and business models utilizing _near-real-time_ Ordinals inscriptions and transfers events.
24+
With **ordhook**, Bitcoin developers can reliably implement feature-rich protocols and business models utilizing _near-real-time_ Ordinals inscriptions and transfers events.
2625

2726
# Quick Start
2827

2928
## Installing `ordhook` from source
3029

31-
```console
30+
```console
3231
$ git clone https://github.com/hirosystems/ordhook.git
3332
$ cd ordhook
3433
$ cargo ordhook-install
@@ -39,13 +38,14 @@ $ cargo ordhook-install
3938
### Explore Ordinal activities in your terminal
4039

4140
Once `ordhook` is installed, Ordinals activities scanning can simply be performed using the following command:
41+
4242
```console
4343
$ ordhook scan blocks --interval 767430:767753 --mainnet
4444
Inscription 6fb976ab49dcec017f1e201e84395983204ae1a7c2abf7ced0a85d692e442799i0 revealed at block #767430 (ordinal_number 1252201400444387, inscription_number 0)
45-
Inscription 26482871f33f1051f450f2da9af275794c0b5f1c61ebf35e4467fb42c2813403i0 revealed at block #767753 (ordinal_number 727624168684699, inscription_number 1)
45+
Inscription 26482871f33f1051f450f2da9af275794c0b5f1c61ebf35e4467fb42c2813403i0 revealed at block #767753 (ordinal_number 727624168684699, inscription_number 1)
4646
```
4747

48-
In this command, an interval of blocks to scan (starting at block `767430`, ending at block `767753`) is being provided. `ordhook` will display inscriptions and transfers activities occurring in the range of the specified blocks.
48+
In this command, an interval of blocks to scan (starting at block `767430`, ending at block `767753`) is being provided. `ordhook` will display inscriptions and transfers activities occurring in the range of the specified blocks.
4949

5050
The activity for a given inscription can be retrieved using the following command:
5151

@@ -56,19 +56,20 @@ Transferred in transaction bc4c30829a9564c0d58e6287195622b53ced54a25711d1b86be7c
5656
```
5757

5858
---
59+
5960
### Stream Ordinal activities to an indexer
6061

6162
`ordhook` is designed to help developers extract ordinals activities (inscriptions and transfers) from the Bitcoin chain and streaming these activities to their indexer / web application.
6263

6364
In order to get started, a `bitcoind` instance with access to the RPC methods `getblockhash` and `getblock` must be running. The RPC calls latency will directly impact the speed of the scans.
6465

65-
*Note: the configuration of a `bitcoind` instance is out of scope for this guide.*
66+
_Note: the configuration of a `bitcoind` instance is out of scope for this guide._
6667

67-
Assuming:
68+
Assuming:
6869

69-
`1)` a `bitcoind` node correctly configured and
70+
`1)` a `bitcoind` node correctly configured and
7071

71-
`2)` a local HTTP server running on port `3000` exposing a `POST /api/events` endpoint,
72+
`2)` a local HTTP server running on port `3000` exposing a `POST /api/events` endpoint,
7273

7374
A configuration file `Ordhook.toml` can be generated using the command:
7475

@@ -77,15 +78,16 @@ $ ordhook config new --mainnet
7778
✔ Generated config file Ordhook.toml
7879
```
7980

80-
After adjusting the `Ordhook.toml` settings to make them match the `bitcoind` configuration, the following command can be ran:
81+
After adjusting the `Ordhook.toml` settings to make them match the `bitcoind` configuration, the following command can be ran:
8182

8283
```
8384
$ ordhook scan blocks --interval 767430:767753 --post-to=http://localhost:3000/api/events --config-path=./Ordhook.toml
8485
```
8586

86-
`ordhook` will retrieve the full Ordinals activities (including the inscriptions content) and send all these informations to the `http://localhost:3000/api/events` HTTP POST endpoint.
87+
`ordhook` will retrieve the full Ordinals activities (including the inscriptions content) and send all these informations to the `http://localhost:3000/api/events` HTTP POST endpoint.
8788

8889
---
90+
8991
### Run `ordhook` as a service for streaming blocks
9092

9193
`ordhook` can be ran as a service for streaming and processing new blocks appended to the Bitcoin blockchain.
@@ -112,6 +114,7 @@ will spin up a HTTP API for managing events destinations.
112114
A comprehensive OpenAPI specification explaining how to interact with this HTTP REST API can be found [here](https://github.com/hirosystems/chainhook/blob/develop/docs/chainhook-openapi.json).
113115

114116
---
117+
115118
### Troubleshooting: Performance and System Requirements
116119

117120
The Ordinals Theory protocol is resource-intensive, demanding significant CPU, memory, and disk capabilities. As we continue to refine and optimize, keep in mind the following system requirements and recommendations to ensure optimal performance:

Diff for: components/ordhook-core/src/core/protocol/inscription_sequencing.rs

+23-20
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ fn get_transactions_to_process(
357357
continue;
358358
}
359359

360-
if let Some(_) = known_transactions.get(&key) {
360+
if let Some(_) = known_transactions.get(&inscription_data.inscription_id) {
361361
continue;
362362
}
363363

@@ -417,8 +417,8 @@ impl<'a> SequenceCursor<'a> {
417417
self.current_block_height = block_height;
418418

419419
let classic = match cursed {
420-
true => self.pick_next_neg_number(ctx),
421-
false => self.pick_next_pos_number(ctx),
420+
true => self.pick_next_neg_classic(ctx),
421+
false => self.pick_next_pos_classic(ctx),
422422
};
423423
let jubilee_height = match network {
424424
Network::Bitcoin => 824544,
@@ -435,7 +435,7 @@ impl<'a> SequenceCursor<'a> {
435435
OrdinalInscriptionNumber { classic, jubilee }
436436
}
437437

438-
fn pick_next_pos_number(&mut self, ctx: &Context) -> i64 {
438+
fn pick_next_pos_classic(&mut self, ctx: &Context) -> i64 {
439439
match self.pos_cursor {
440440
None => {
441441
match find_nth_classic_pos_number_at_block_height(
@@ -455,7 +455,7 @@ impl<'a> SequenceCursor<'a> {
455455
}
456456

457457
fn pick_next_jubilee_number(&mut self, ctx: &Context) -> i64 {
458-
match self.pos_cursor {
458+
match self.jubilee_cursor {
459459
None => {
460460
match find_nth_jubilee_number_at_block_height(
461461
&self.current_block_height,
@@ -473,7 +473,7 @@ impl<'a> SequenceCursor<'a> {
473473
}
474474
}
475475

476-
fn pick_next_neg_number(&mut self, ctx: &Context) -> i64 {
476+
fn pick_next_neg_classic(&mut self, ctx: &Context) -> i64 {
477477
match self.neg_cursor {
478478
None => {
479479
match find_nth_classic_neg_number_at_block_height(
@@ -492,12 +492,12 @@ impl<'a> SequenceCursor<'a> {
492492
}
493493
}
494494

495-
pub fn increment_neg_cursor(&mut self, ctx: &Context) {
496-
self.neg_cursor = Some(self.pick_next_neg_number(ctx));
495+
pub fn increment_neg_classic(&mut self, ctx: &Context) {
496+
self.neg_cursor = Some(self.pick_next_neg_classic(ctx));
497497
}
498498

499-
pub fn increment_pos_number(&mut self, ctx: &Context) {
500-
self.pos_cursor = Some(self.pick_next_pos_number(ctx))
499+
pub fn increment_pos_classic(&mut self, ctx: &Context) {
500+
self.pos_cursor = Some(self.pick_next_pos_classic(ctx));
501501
}
502502

503503
pub fn increment_jubilee_number(&mut self, ctx: &Context) {
@@ -599,9 +599,9 @@ pub fn augment_block_with_ordinals_inscriptions_data(
599599
inscription_data.inscription_number = inscription_number;
600600

601601
if is_curse {
602-
sequence_cursor.increment_neg_cursor(ctx);
602+
sequence_cursor.increment_neg_classic(ctx);
603603
} else {
604-
sequence_cursor.increment_pos_number(ctx);
604+
sequence_cursor.increment_pos_classic(ctx);
605605
};
606606

607607
ctx.try_log(|logger| {
@@ -756,10 +756,11 @@ fn augment_transaction_with_ordinals_inscriptions_data(
756756
);
757757
});
758758

759+
sequence_cursor.increment_jubilee_number(ctx);
759760
if is_cursed {
760-
sequence_cursor.increment_neg_cursor(ctx);
761+
sequence_cursor.increment_neg_classic(ctx);
761762
} else {
762-
sequence_cursor.increment_pos_number(ctx);
763+
sequence_cursor.increment_pos_classic(ctx);
763764
}
764765
inscription_subindex += 1;
765766
}
@@ -773,22 +774,24 @@ fn consolidate_transaction_with_pre_computed_inscription_data(
773774
tx_index: usize,
774775
coinbase_txid: &TransactionIdentifier,
775776
network: &Network,
776-
inscriptions_data: &mut BTreeMap<(TransactionIdentifier, usize), TraversalResult>,
777+
inscriptions_data: &mut BTreeMap<String, TraversalResult>,
777778
_ctx: &Context,
778779
) {
780+
let mut subindex = 0;
779781
for operation in tx.metadata.ordinal_operations.iter_mut() {
780782
let inscription = match operation {
781783
OrdinalOperation::InscriptionRevealed(ref mut inscription) => inscription,
782784
OrdinalOperation::InscriptionTransferred(_) => continue,
783785
};
784786

785-
let Some(traversal) = inscriptions_data.get(&(
786-
tx.transaction_identifier.clone(),
787-
inscription.inscription_input_index,
788-
)) else {
787+
let inscription_id = format_inscription_id(&tx.transaction_identifier, subindex);
788+
let Some(traversal) = inscriptions_data.get(&inscription_id) else {
789+
// Should we remove the operation instead
789790
continue;
790791
};
792+
subindex += 1;
791793

794+
inscription.inscription_id = inscription_id.clone();
792795
inscription.ordinal_offset = traversal.get_ordinal_coinbase_offset();
793796
inscription.ordinal_block_height = traversal.get_ordinal_coinbase_height();
794797
inscription.ordinal_number = traversal.ordinal_number;
@@ -857,7 +860,7 @@ pub fn consolidate_block_with_pre_computed_ordinals_data(
857860
let results =
858861
find_all_inscriptions_in_block(&block.block_identifier.index, inscriptions_db_tx, ctx);
859862
// TODO: investigate, sporadically the set returned is empty, and requires a retry.
860-
if results.is_empty() && expected_inscriptions_count > 0 {
863+
if results.len() != expected_inscriptions_count {
861864
ctx.try_log(|logger| {
862865
warn!(
863866
logger,

Diff for: components/ordhook-core/src/db/mod.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1096,7 +1096,7 @@ pub fn find_all_inscriptions_in_block(
10961096
block_height: &u64,
10971097
inscriptions_db_tx: &Connection,
10981098
ctx: &Context,
1099-
) -> BTreeMap<(TransactionIdentifier, usize), TraversalResult> {
1099+
) -> BTreeMap<String, TraversalResult> {
11001100
let transfers_data = find_all_transfers_in_block(block_height, inscriptions_db_tx, ctx);
11011101

11021102
let args: &[&dyn ToSql] = &[&block_height.to_sql().unwrap()];
@@ -1159,10 +1159,7 @@ pub fn find_all_inscriptions_in_block(
11591159
transaction_identifier_inscription: transaction_identifier_inscription.clone(),
11601160
transfer_data: transfer_data.clone(),
11611161
};
1162-
results.insert(
1163-
(transaction_identifier_inscription, inscription_input_index),
1164-
traversal,
1165-
);
1162+
results.insert(inscription_id, traversal);
11661163
}
11671164
Ok(None) => break,
11681165
Err(e) => {

0 commit comments

Comments
 (0)