Skip to content

Commit f55a5ee

Browse files
author
Ludo Galabru
committed
feat: ordinal inscription_transfer code complete
1 parent 5a00135 commit f55a5ee

File tree

34 files changed

+1207
-868
lines changed

34 files changed

+1207
-868
lines changed

Cargo.lock

+5-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/chainhook-cli/Cargo.toml

-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ serde_derive = "1"
1414
redis = "0.21.5"
1515
serde-redis = "0.12.0"
1616
hex = "0.4.3"
17-
ciborium = "0.2.0"
1817
rand = "0.8.5"
1918
# tikv-client = { git = "https://github.com/tikv/client-rust.git", rev = "8f54e6114227718e256027df2577bbacdf425f86" }
2019
# raft-proto = { git = "https://github.com/tikv/raft-rs", rev="f73766712a538c2f6eb135b455297ad6c03fc58d", version = "0.7.0"}
@@ -37,8 +36,6 @@ flume = "0.10.14"
3736
ansi_term = "0.12.1"
3837
atty = "0.2.14"
3938
crossbeam-channel = "0.5.6"
40-
rusqlite = { version = "0.27.0", features = ["bundled"] }
41-
threadpool = "1.8.1"
4239

4340
[dev-dependencies]
4441
criterion = "0.3"

components/chainhook-cli/src/cli/mod.rs

+43-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
use crate::block::DigestingCommand;
22
use crate::config::Config;
33
use crate::node::Node;
4-
use crate::scan::bitcoin::{
5-
build_bitcoin_traversal_local_storage, scan_bitcoin_chain_with_predicate,
6-
};
4+
use crate::scan::bitcoin::scan_bitcoin_chain_with_predicate;
75
use crate::scan::stacks::scan_stacks_chain_with_predicate;
86

97
use chainhook_event_observer::chainhooks::types::ChainhookFullSpecification;
8+
use chainhook_event_observer::indexer::ordinals::db::{
9+
build_bitcoin_traversal_local_storage, open_readonly_ordinals_db_conn,
10+
retrieve_satoshi_point_using_local_storage,
11+
};
12+
use chainhook_event_observer::indexer::ordinals::ord::height::Height;
13+
use chainhook_event_observer::observer::BitcoinConfig;
1014
use chainhook_event_observer::utils::Context;
15+
use chainhook_types::{BlockIdentifier, TransactionIdentifier};
1116
use clap::{Parser, Subcommand};
1217
use ctrlc;
1318
use hiro_system_kit;
@@ -142,6 +147,8 @@ struct BuildOrdinalsTraversalsCommand {
142147
pub start_block: u64,
143148
/// Starting block
144149
pub end_block: u64,
150+
/// # of Networking thread
151+
pub network_threads: usize,
145152
/// Target Devnet network
146153
#[clap(
147154
long = "devnet",
@@ -175,6 +182,8 @@ struct BuildOrdinalsTraversalsCommand {
175182

176183
#[derive(Parser, PartialEq, Clone, Debug)]
177184
struct GetSatoshiCommand {
185+
/// Block height
186+
pub block_height: u64,
178187
/// Txid
179188
pub txid: String,
180189
/// Output index
@@ -276,19 +285,46 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
276285
},
277286
Command::Protocols(ProtocolsCommand::Ordinals(subcmd)) => match subcmd {
278287
OrdinalsCommand::Satoshi(cmd) => {
279-
let _config =
288+
let config =
280289
Config::default(cmd.devnet, cmd.testnet, cmd.mainnet, &cmd.config_path)?;
290+
let transaction_identifier = TransactionIdentifier {
291+
hash: cmd.txid.clone(),
292+
};
293+
let block_identifier = BlockIdentifier {
294+
index: cmd.block_height,
295+
hash: "".into(),
296+
};
297+
let storage_conn =
298+
open_readonly_ordinals_db_conn(&config.expected_cache_path()).unwrap();
299+
let (block_height, offset) = retrieve_satoshi_point_using_local_storage(
300+
&storage_conn,
301+
&block_identifier,
302+
&transaction_identifier,
303+
&ctx,
304+
)?;
305+
let satoshi_id = Height(block_height).starting_sat().0 + offset;
306+
info!(
307+
ctx.expect_logger(),
308+
"Block: {block_height}, Offset {offset}:, Satoshi ID: {satoshi_id}",
309+
);
281310
}
282311
OrdinalsCommand::Traversals(cmd) => {
283312
let config =
284313
Config::default(cmd.devnet, cmd.testnet, cmd.mainnet, &cmd.config_path)?;
285314

286-
build_bitcoin_traversal_local_storage(
287-
config,
315+
let bitcoin_config = BitcoinConfig {
316+
username: config.network.bitcoin_node_rpc_username.clone(),
317+
password: config.network.bitcoin_node_rpc_password.clone(),
318+
rpc_url: config.network.bitcoin_node_rpc_url.clone(),
319+
};
320+
321+
let _ = build_bitcoin_traversal_local_storage(
322+
&bitcoin_config,
323+
&config.expected_cache_path(),
288324
cmd.start_block,
289325
cmd.end_block,
290326
&ctx,
291-
6,
327+
cmd.network_threads,
292328
)
293329
.await;
294330
}

components/chainhook-cli/src/config/mod.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ use std::path::PathBuf;
1010

1111
const DEFAULT_MAINNET_TSV_ARCHIVE: &str = "https://storage.googleapis.com/hirosystems-archive/mainnet/api/mainnet-blockchain-api-latest.tar.gz";
1212
const DEFAULT_TESTNET_TSV_ARCHIVE: &str = "https://storage.googleapis.com/hirosystems-archive/testnet/api/testnet-blockchain-api-latest.tar.gz";
13+
// const DEFAULT_MAINNET_TSV_ARCHIVE: &str = "https://archive.hiro.so/mainnet/stacks-blockchain-api/mainnet-stacks-blockchain-api-latest.gz";
14+
// const DEFAULT_TESTNET_TSV_ARCHIVE: &str = "https://archive.hiro.so/testnet/stacks-blockchain-api/testnet-stacks-blockchain-api-latest.gz";
1315

1416
#[derive(Clone, Debug)]
1517
pub struct Config {
@@ -181,13 +183,6 @@ impl Config {
181183
destination_path
182184
}
183185

184-
pub fn get_bitcoin_block_traversal_db_path(&self) -> PathBuf {
185-
let mut destination_path = PathBuf::new();
186-
destination_path.push(&self.storage.cache_path);
187-
destination_path.push("bitcoin_block_traversal.sqlite");
188-
destination_path
189-
}
190-
191186
pub fn expected_stacks_node_event_source(&self) -> &String {
192187
for source in self.event_sources.iter() {
193188
if let EventSourceConfig::StacksNode(config) = source {

components/chainhook-cli/src/node/mod.rs

+69-55
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,16 @@
11
use crate::config::Config;
2-
use crate::node::ordinals::inscription_id::InscriptionId;
3-
use chainhook_event_observer::bitcoincore_rpc::bitcoin::BlockHash;
42
use chainhook_event_observer::bitcoincore_rpc::jsonrpc;
53
use chainhook_event_observer::chainhooks::bitcoin::{
64
handle_bitcoin_hook_action, BitcoinChainhookOccurrence, BitcoinTriggerChainhook,
75
};
86
use chainhook_event_observer::chainhooks::types::{
9-
BitcoinPredicateType, ChainhookConfig, OrdinalOperations, Protocols,
7+
BitcoinPredicateType, ChainhookConfig, ChainhookFullSpecification, OrdinalOperations, Protocols,
108
};
11-
use chainhook_event_observer::indexer::ordinals::indexing::entry::Entry;
12-
use chainhook_event_observer::indexer::ordinals::indexing::{
13-
HEIGHT_TO_BLOCK_HASH, INSCRIPTION_NUMBER_TO_INSCRIPTION_ID,
14-
};
15-
use chainhook_event_observer::indexer::ordinals::{self, initialize_ordinal_index};
9+
use chainhook_event_observer::indexer::ordinals::{self, ord::initialize_ordinal_index};
1610
use chainhook_event_observer::indexer::{self, BitcoinChainContext};
1711
use chainhook_event_observer::observer::{
18-
start_event_observer, EventObserverConfig, ObserverEvent,
12+
start_event_observer, ApiKey, EventObserverConfig, ObserverEvent,
1913
};
20-
use chainhook_event_observer::redb::ReadableTable;
2114
use chainhook_event_observer::utils::{file_append, send_request, Context};
2215
use chainhook_event_observer::{
2316
chainhooks::stacks::{
@@ -71,7 +64,7 @@ impl Node {
7164
for key in chainhooks_to_load.iter() {
7265
let chainhook = match redis_con.hget::<_, _, String>(key, "specification") {
7366
Ok(spec) => {
74-
ChainhookSpecification::deserialize_specification(&spec, key).unwrap()
67+
ChainhookFullSpecification::deserialize_specification(&spec, key).unwrap()
7568
// todo
7669
}
7770
Err(e) => {
@@ -84,8 +77,30 @@ impl Node {
8477
continue;
8578
}
8679
};
87-
// TODO
88-
// chainhook_config.register_hook(chainhook);
80+
81+
match chainhook_config.register_hook(
82+
(
83+
&self.config.network.bitcoin_network,
84+
&self.config.network.stacks_network,
85+
),
86+
chainhook,
87+
&ApiKey(None),
88+
) {
89+
Ok(spec) => {
90+
info!(
91+
self.ctx.expect_logger(),
92+
"Predicate {} retrieved from storage and loaded",
93+
spec.uuid(),
94+
);
95+
}
96+
Err(e) => {
97+
error!(
98+
self.ctx.expect_logger(),
99+
"Failed loading predicate from storage: {}",
100+
e.to_string()
101+
);
102+
}
103+
}
89104
}
90105
}
91106

@@ -128,7 +143,6 @@ impl Node {
128143
panic!()
129144
}
130145
};
131-
let mut bitcoin_context = BitcoinChainContext::new(Some(ordinal_index));
132146

133147
let context_cloned = self.ctx.clone();
134148
let _ = std::thread::spawn(move || {
@@ -311,50 +325,51 @@ impl Node {
311325
}
312326
ChainhookSpecification::Bitcoin(predicate_spec) => {
313327
let mut inscriptions_hints = BTreeMap::new();
314-
let mut use_hinting = false;
328+
let use_hinting = false;
315329
if let BitcoinPredicateType::Protocol(Protocols::Ordinal(
316330
OrdinalOperations::InscriptionRevealed,
317331
)) = &predicate_spec.predicate
318332
{
319-
if let Some(ref ordinal_index) = bitcoin_context.ordinal_index {
320-
for (inscription_number, inscription_id) in ordinal_index
321-
.database
322-
.begin_read()
323-
.unwrap()
324-
.open_table(INSCRIPTION_NUMBER_TO_INSCRIPTION_ID)
325-
.unwrap()
326-
.iter()
327-
.unwrap()
328-
{
329-
let inscription =
330-
InscriptionId::load(*inscription_id.value());
331-
println!(
332-
"{} -> {}",
333-
inscription_number.value(),
334-
inscription
335-
);
336-
337-
let entry = ordinal_index
338-
.get_inscription_entry(inscription)
339-
.unwrap()
340-
.unwrap();
341-
println!("{:?}", entry);
342-
343-
let blockhash = ordinal_index
344-
.database
345-
.begin_read()
346-
.unwrap()
347-
.open_table(HEIGHT_TO_BLOCK_HASH)
348-
.unwrap()
349-
.get(&entry.height)
350-
.unwrap()
351-
.map(|k| BlockHash::load(*k.value()))
352-
.unwrap();
353-
354-
inscriptions_hints.insert(entry.height, blockhash);
355-
use_hinting = true;
356-
}
357-
}
333+
inscriptions_hints.insert(1, 1);
334+
// if let Some(ref ordinal_index) = bitcoin_context.ordinal_index {
335+
// for (inscription_number, inscription_id) in ordinal_index
336+
// .database
337+
// .begin_read()
338+
// .unwrap()
339+
// .open_table(INSCRIPTION_NUMBER_TO_INSCRIPTION_ID)
340+
// .unwrap()
341+
// .iter()
342+
// .unwrap()
343+
// {
344+
// let inscription =
345+
// InscriptionId::load(*inscription_id.value());
346+
// println!(
347+
// "{} -> {}",
348+
// inscription_number.value(),
349+
// inscription
350+
// );
351+
352+
// let entry = ordinal_index
353+
// .get_inscription_entry(inscription)
354+
// .unwrap()
355+
// .unwrap();
356+
// println!("{:?}", entry);
357+
358+
// let blockhash = ordinal_index
359+
// .database
360+
// .begin_read()
361+
// .unwrap()
362+
// .open_table(HEIGHT_TO_BLOCK_HASH)
363+
// .unwrap()
364+
// .get(&entry.height)
365+
// .unwrap()
366+
// .map(|k| BlockHash::load(*k.value()))
367+
// .unwrap();
368+
369+
// inscriptions_hints.insert(entry.height, blockhash);
370+
// use_hinting = true;
371+
// }
372+
// }
358373
}
359374

360375
let start_block = match predicate_spec.start_block {
@@ -469,7 +484,6 @@ impl Node {
469484
let block = indexer::bitcoin::standardize_bitcoin_block(
470485
&self.config.network,
471486
raw_block,
472-
&mut bitcoin_context,
473487
&self.ctx,
474488
)?;
475489

0 commit comments

Comments
 (0)