mirror of
https://github.com/alexgo-io/bitcoin-indexer.git
synced 2026-01-12 22:43:06 +08:00
* fix: synthetic predicate * fix: set height 0 for regtest, etc. * fix: issue #296 * chore: update chainhook-sdk * fix: use latest chainhook * fix: augment block with brc20 while indexing * fix: force input 0 --------- Co-authored-by: Rafael Cardenas <rafael@rafaelcr.com>
This commit is contained in:
36
Cargo.lock
generated
36
Cargo.lock
generated
@@ -494,9 +494,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chainhook-sdk"
|
||||
version = "0.12.8"
|
||||
version = "0.12.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd54af8c8b55ce530013e2dd510d76be08e9132c9918f81d8a0d3d86b6e4bde"
|
||||
checksum = "14eeb8a1a055202ca86122c9508dc4f9d9cd8643ef9f25773173b645c33b09ac"
|
||||
dependencies = [
|
||||
"base58",
|
||||
"base64 0.21.5",
|
||||
@@ -517,7 +517,7 @@ dependencies = [
|
||||
"regex",
|
||||
"reqwest",
|
||||
"rocket",
|
||||
"schemars 0.8.16",
|
||||
"schemars 0.8.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde",
|
||||
"serde-hex",
|
||||
"serde_derive",
|
||||
@@ -535,7 +535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63f0d358e5c530dd6888e4678ef4ba3f7782525653a1012d33e96a48020c418d"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"schemars 0.8.16",
|
||||
"schemars 0.8.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
@@ -2472,7 +2472,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64853d7ab065474e87696f7601cee817d200e86c42e04004e005cb3e20c3c5"
|
||||
dependencies = [
|
||||
"log",
|
||||
"schemars 0.8.16",
|
||||
"schemars 0.8.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
@@ -2520,7 +2520,7 @@ dependencies = [
|
||||
"rocket_okapi",
|
||||
"rocksdb",
|
||||
"rusqlite",
|
||||
"schemars 0.8.12",
|
||||
"schemars 0.8.16 (git+https://github.com/hirosystems/schemars.git?branch=feat-chainhook-fixes)",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
@@ -3237,7 +3237,7 @@ dependencies = [
|
||||
"okapi",
|
||||
"rocket",
|
||||
"rocket_okapi_codegen",
|
||||
"schemars 0.8.16",
|
||||
"schemars 0.8.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
@@ -3387,11 +3387,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "schemars"
|
||||
version = "0.8.12"
|
||||
source = "git+https://github.com/hirosystems/schemars.git?branch=feat-chainhook-fixes#15fdd4711700114d57c090aad62516593bd4ca6d"
|
||||
version = "0.8.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29"
|
||||
dependencies = [
|
||||
"dyn-clone",
|
||||
"schemars_derive 0.8.12",
|
||||
"indexmap 1.9.3",
|
||||
"schemars_derive 0.8.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
@@ -3399,20 +3401,19 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "schemars"
|
||||
version = "0.8.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29"
|
||||
source = "git+https://github.com/hirosystems/schemars.git?branch=feat-chainhook-fixes#d0c10b50478a06198a54e5b90be460112b38b357"
|
||||
dependencies = [
|
||||
"dyn-clone",
|
||||
"indexmap 1.9.3",
|
||||
"schemars_derive 0.8.16",
|
||||
"schemars_derive 0.8.16 (git+https://github.com/hirosystems/schemars.git?branch=feat-chainhook-fixes)",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schemars_derive"
|
||||
version = "0.8.12"
|
||||
source = "git+https://github.com/hirosystems/schemars.git?branch=feat-chainhook-fixes#15fdd4711700114d57c090aad62516593bd4ca6d"
|
||||
version = "0.8.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -3423,8 +3424,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "schemars_derive"
|
||||
version = "0.8.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967"
|
||||
source = "git+https://github.com/hirosystems/schemars.git?branch=feat-chainhook-fixes#d0c10b50478a06198a54e5b90be460112b38b357"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
@@ -4,7 +4,7 @@ use clap::{Parser, Subcommand};
|
||||
use hiro_system_kit;
|
||||
use ordhook::chainhook_sdk::bitcoincore_rpc::{Auth, Client, RpcApi};
|
||||
use ordhook::chainhook_sdk::chainhooks::types::{
|
||||
BitcoinChainhookSpecification, HttpHook, InscriptionFeedData,
|
||||
BitcoinChainhookSpecification, HttpHook, InscriptionFeedData, OrdinalsMetaProtocol,
|
||||
};
|
||||
use ordhook::chainhook_sdk::chainhooks::types::{
|
||||
BitcoinPredicateType, ChainhookFullSpecification, HookAction, OrdinalOperations,
|
||||
@@ -31,11 +31,12 @@ use ordhook::db::{
|
||||
open_readonly_ordhook_db_conn_rocks_db, BlockBytesCursor,
|
||||
};
|
||||
use ordhook::download::download_ordinals_dataset_if_required;
|
||||
use ordhook::{hex, initialize_db};
|
||||
use ordhook::scan::bitcoin::scan_bitcoin_chainstate_via_rpc_using_predicate;
|
||||
use ordhook::service::observers::initialize_observers_db;
|
||||
use ordhook::service::{start_observer_forwarding, Service};
|
||||
use ordhook::{hex, initialize_db};
|
||||
use reqwest::Client as HttpClient;
|
||||
use std::collections::HashSet;
|
||||
use std::io::{BufReader, Read};
|
||||
use std::path::PathBuf;
|
||||
use std::process;
|
||||
@@ -972,6 +973,12 @@ pub fn build_predicate_from_cli(
|
||||
(Some(start), None) => (Some(start), None, None),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let mut meta_protocols: Option<HashSet<OrdinalsMetaProtocol>> = None;
|
||||
if config.meta_protocols.brc20 {
|
||||
let mut meta = HashSet::<OrdinalsMetaProtocol>::new();
|
||||
meta.insert(OrdinalsMetaProtocol::All);
|
||||
meta_protocols = Some(meta.clone());
|
||||
}
|
||||
let predicate = BitcoinChainhookSpecification {
|
||||
network: config.network.bitcoin_network.clone(),
|
||||
uuid: post_to.to_string(),
|
||||
@@ -989,9 +996,7 @@ pub fn build_predicate_from_cli(
|
||||
expired_at: None,
|
||||
enabled: true,
|
||||
predicate: BitcoinPredicateType::OrdinalsProtocol(OrdinalOperations::InscriptionFeed(
|
||||
InscriptionFeedData {
|
||||
meta_protocols: None,
|
||||
},
|
||||
InscriptionFeedData { meta_protocols },
|
||||
)),
|
||||
action: HookAction::HttpPost(HttpHook {
|
||||
url: post_to.to_string(),
|
||||
|
||||
@@ -11,8 +11,8 @@ serde_derive = "1"
|
||||
hex = "0.4.3"
|
||||
rand = "0.8.5"
|
||||
lru = "0.12.3"
|
||||
chainhook-sdk = { version = "=0.12.8", features = ["zeromq"] }
|
||||
# chainhook-sdk = { version = "=0.12.5", path = "../../../chainhook/components/chainhook-sdk", features = ["zeromq"] }
|
||||
chainhook-sdk = { version = "=0.12.10", features = ["zeromq"] }
|
||||
# chainhook-sdk = { version = "=0.12.10", path = "../../../chainhook/components/chainhook-sdk", features = ["zeromq"] }
|
||||
hiro-system-kit = "0.3.1"
|
||||
reqwest = { version = "0.11", default-features = false, features = [
|
||||
"stream",
|
||||
@@ -35,7 +35,7 @@ dashmap = "5.4.0"
|
||||
fxhash = "0.2.1"
|
||||
rusqlite = { version = "0.28.0", features = ["bundled"] }
|
||||
anyhow = { version = "1.0.56", features = ["backtrace"] }
|
||||
schemars = { version = "0.8.10", git = "https://github.com/hirosystems/schemars.git", branch = "feat-chainhook-fixes" }
|
||||
schemars = { version = "0.8.16", git = "https://github.com/hirosystems/schemars.git", branch = "feat-chainhook-fixes" }
|
||||
progressing = '3'
|
||||
futures = "0.3.28"
|
||||
rocksdb = { version = "0.21.0", default-features = false, features = [
|
||||
|
||||
@@ -9,17 +9,17 @@ pub mod test_utils;
|
||||
pub fn brc20_activation_height(network: &BitcoinNetwork) -> u64 {
|
||||
match network {
|
||||
BitcoinNetwork::Mainnet => 779832,
|
||||
BitcoinNetwork::Regtest => todo!(),
|
||||
BitcoinNetwork::Testnet => todo!(),
|
||||
BitcoinNetwork::Signet => todo!(),
|
||||
BitcoinNetwork::Regtest => 0,
|
||||
BitcoinNetwork::Testnet => 0,
|
||||
BitcoinNetwork::Signet => 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn brc20_self_mint_activation_height(network: &BitcoinNetwork) -> u64 {
|
||||
match network {
|
||||
BitcoinNetwork::Mainnet => 837090,
|
||||
BitcoinNetwork::Regtest => todo!(),
|
||||
BitcoinNetwork::Testnet => todo!(),
|
||||
BitcoinNetwork::Signet => todo!(),
|
||||
BitcoinNetwork::Regtest => 0,
|
||||
BitcoinNetwork::Testnet => 0,
|
||||
BitcoinNetwork::Signet => 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,6 @@ pub fn resolve_absolute_pointer(inputs: &Vec<u64>, absolute_pointer_value: u64)
|
||||
}
|
||||
|
||||
pub fn compute_next_satpoint_data(
|
||||
_tx_index: usize,
|
||||
input_index: usize,
|
||||
inputs: &Vec<u64>,
|
||||
outputs: &Vec<u64>,
|
||||
@@ -220,40 +219,39 @@ pub fn should_sync_ordhook_db(
|
||||
#[test]
|
||||
fn test_identify_next_output_index_destination() {
|
||||
assert_eq!(
|
||||
compute_next_satpoint_data(0, 0, &vec![20, 30, 45], &vec![20, 30, 45], 10, None),
|
||||
compute_next_satpoint_data(0, &vec![20, 30, 45], &vec![20, 30, 45], 10, None),
|
||||
SatPosition::Output((0, 10))
|
||||
);
|
||||
assert_eq!(
|
||||
compute_next_satpoint_data(0, 0, &vec![20, 30, 45], &vec![20, 30, 45], 20, None),
|
||||
compute_next_satpoint_data(0, &vec![20, 30, 45], &vec![20, 30, 45], 20, None),
|
||||
SatPosition::Output((1, 0))
|
||||
);
|
||||
assert_eq!(
|
||||
compute_next_satpoint_data(0, 1, &vec![20, 30, 45], &vec![20, 30, 45], 25, None),
|
||||
compute_next_satpoint_data(1, &vec![20, 30, 45], &vec![20, 30, 45], 25, None),
|
||||
SatPosition::Output((1, 25))
|
||||
);
|
||||
assert_eq!(
|
||||
compute_next_satpoint_data(0, 1, &vec![20, 30, 45], &vec![20, 5, 45], 26, None),
|
||||
compute_next_satpoint_data(1, &vec![20, 30, 45], &vec![20, 5, 45], 26, None),
|
||||
SatPosition::Output((2, 21))
|
||||
);
|
||||
assert_eq!(
|
||||
compute_next_satpoint_data(0, 1, &vec![10, 10, 10], &vec![30], 20, None),
|
||||
compute_next_satpoint_data(1, &vec![10, 10, 10], &vec![30], 20, None),
|
||||
SatPosition::Fee(0)
|
||||
);
|
||||
assert_eq!(
|
||||
compute_next_satpoint_data(0, 0, &vec![10, 10, 10], &vec![30], 30, None),
|
||||
compute_next_satpoint_data(0, &vec![10, 10, 10], &vec![30], 30, None),
|
||||
SatPosition::Fee(0)
|
||||
);
|
||||
assert_eq!(
|
||||
compute_next_satpoint_data(0, 0, &vec![10, 10, 10], &vec![30], 0, None),
|
||||
compute_next_satpoint_data(0, &vec![10, 10, 10], &vec![30], 0, None),
|
||||
SatPosition::Output((0, 0))
|
||||
);
|
||||
assert_eq!(
|
||||
compute_next_satpoint_data(0, 2, &vec![20, 30, 45], &vec![20, 30, 45], 95, None),
|
||||
compute_next_satpoint_data(2, &vec![20, 30, 45], &vec![20, 30, 45], 95, None),
|
||||
SatPosition::Fee(50)
|
||||
);
|
||||
assert_eq!(
|
||||
compute_next_satpoint_data(
|
||||
0,
|
||||
2,
|
||||
&vec![1000, 600, 546, 63034],
|
||||
&vec![1600, 10000, 15000],
|
||||
@@ -264,7 +262,6 @@ fn test_identify_next_output_index_destination() {
|
||||
);
|
||||
assert_eq!(
|
||||
compute_next_satpoint_data(
|
||||
0,
|
||||
3,
|
||||
&vec![6100, 148660, 103143, 7600],
|
||||
&vec![81434, 173995],
|
||||
|
||||
@@ -333,7 +333,7 @@ pub fn process_block(
|
||||
|
||||
if let Some(brc20_db_tx) = brc20_db_tx {
|
||||
write_brc20_block_operations(
|
||||
&block,
|
||||
block,
|
||||
&mut brc20_operation_map,
|
||||
brc20_cache,
|
||||
&brc20_db_tx,
|
||||
|
||||
@@ -617,7 +617,7 @@ pub fn augment_block_with_ordinals_inscriptions_data(
|
||||
|
||||
let network = get_bitcoin_network(&block.metadata.network);
|
||||
let coinbase_subsidy = Height(block.block_identifier.index).subsidy();
|
||||
let coinbase_txid = &block.transactions[0].transaction_identifier.clone();
|
||||
let coinbase_tx = &block.transactions[0].clone();
|
||||
let mut cumulated_fees = 0u64;
|
||||
|
||||
for (tx_index, tx) in block.transactions.iter_mut().enumerate() {
|
||||
@@ -628,7 +628,7 @@ pub fn augment_block_with_ordinals_inscriptions_data(
|
||||
sequence_cursor,
|
||||
&network,
|
||||
inscriptions_data,
|
||||
coinbase_txid,
|
||||
coinbase_tx,
|
||||
coinbase_subsidy,
|
||||
&mut cumulated_fees,
|
||||
&mut sats_overflows,
|
||||
@@ -684,7 +684,7 @@ fn augment_transaction_with_ordinals_inscriptions_data(
|
||||
sequence_cursor: &mut SequenceCursor,
|
||||
network: &Network,
|
||||
inscriptions_data: &mut BTreeMap<(TransactionIdentifier, usize, u64), TraversalResult>,
|
||||
coinbase_txid: &TransactionIdentifier,
|
||||
coinbase_tx: &BitcoinTransactionData,
|
||||
coinbase_subsidy: u64,
|
||||
cumulated_fees: &mut u64,
|
||||
sats_overflows: &mut VecDeque<(usize, usize)>,
|
||||
@@ -773,11 +773,10 @@ fn augment_transaction_with_ordinals_inscriptions_data(
|
||||
|
||||
let (destination, satpoint_post_transfer, output_value) = compute_satpoint_post_transfer(
|
||||
&&*tx,
|
||||
tx_index,
|
||||
input_index,
|
||||
relative_offset,
|
||||
network,
|
||||
coinbase_txid,
|
||||
coinbase_tx,
|
||||
coinbase_subsidy,
|
||||
cumulated_fees,
|
||||
ctx,
|
||||
@@ -842,7 +841,7 @@ fn augment_transaction_with_ordinals_inscriptions_data(
|
||||
fn consolidate_transaction_with_pre_computed_inscription_data(
|
||||
tx: &mut BitcoinTransactionData,
|
||||
tx_index: usize,
|
||||
coinbase_txid: &TransactionIdentifier,
|
||||
coinbase_tx: &BitcoinTransactionData,
|
||||
coinbase_subsidy: u64,
|
||||
cumulated_fees: &mut u64,
|
||||
network: &Network,
|
||||
@@ -889,11 +888,10 @@ fn consolidate_transaction_with_pre_computed_inscription_data(
|
||||
// Compute satpoint_post_inscription
|
||||
let (destination, satpoint_post_transfer, output_value) = compute_satpoint_post_transfer(
|
||||
tx,
|
||||
tx_index,
|
||||
input_index,
|
||||
relative_offset,
|
||||
network,
|
||||
coinbase_txid,
|
||||
coinbase_tx,
|
||||
coinbase_subsidy,
|
||||
cumulated_fees,
|
||||
ctx,
|
||||
@@ -930,7 +928,7 @@ pub fn consolidate_block_with_pre_computed_ordinals_data(
|
||||
) {
|
||||
let network = get_bitcoin_network(&block.metadata.network);
|
||||
let coinbase_subsidy = Height(block.block_identifier.index).subsidy();
|
||||
let coinbase_txid = &block.transactions[0].transaction_identifier.clone();
|
||||
let coinbase_tx = &block.transactions[0].clone();
|
||||
let mut cumulated_fees = 0;
|
||||
let expected_inscriptions_count = get_inscriptions_revealed_in_block(&block).len();
|
||||
let mut inscriptions_data = loop {
|
||||
@@ -959,7 +957,7 @@ pub fn consolidate_block_with_pre_computed_ordinals_data(
|
||||
consolidate_transaction_with_pre_computed_inscription_data(
|
||||
tx,
|
||||
tx_index,
|
||||
coinbase_txid,
|
||||
&coinbase_tx,
|
||||
coinbase_subsidy,
|
||||
&mut cumulated_fees,
|
||||
&network,
|
||||
@@ -973,7 +971,7 @@ pub fn consolidate_block_with_pre_computed_ordinals_data(
|
||||
tx,
|
||||
tx_index,
|
||||
&network,
|
||||
&coinbase_txid,
|
||||
&coinbase_tx,
|
||||
coinbase_subsidy,
|
||||
&mut cumulated_fees,
|
||||
inscriptions_db_tx,
|
||||
|
||||
@@ -4,7 +4,7 @@ use chainhook_sdk::{
|
||||
bitcoincore_rpc_json::bitcoin::{Address, Network, ScriptBuf},
|
||||
types::{
|
||||
BitcoinBlockData, BitcoinTransactionData, OrdinalInscriptionTransferData,
|
||||
OrdinalInscriptionTransferDestination, OrdinalOperation, TransactionIdentifier,
|
||||
OrdinalInscriptionTransferDestination, OrdinalOperation,
|
||||
},
|
||||
utils::Context,
|
||||
};
|
||||
@@ -31,14 +31,14 @@ pub fn augment_block_with_ordinals_transfer_data(
|
||||
|
||||
let network = get_bitcoin_network(&block.metadata.network);
|
||||
let coinbase_subsidy = Height(block.block_identifier.index).subsidy();
|
||||
let coinbase_txid = &block.transactions[0].transaction_identifier.clone();
|
||||
let coinbase_tx = &block.transactions[0].clone();
|
||||
let mut cumulated_fees = 0;
|
||||
for (tx_index, tx) in block.transactions.iter_mut().enumerate() {
|
||||
let transfers = augment_transaction_with_ordinals_transfers_data(
|
||||
tx,
|
||||
tx_index,
|
||||
&network,
|
||||
&coinbase_txid,
|
||||
&coinbase_tx,
|
||||
coinbase_subsidy,
|
||||
&mut cumulated_fees,
|
||||
inscriptions_db_tx,
|
||||
@@ -73,11 +73,10 @@ pub fn augment_block_with_ordinals_transfer_data(
|
||||
|
||||
pub fn compute_satpoint_post_transfer(
|
||||
tx: &BitcoinTransactionData,
|
||||
tx_index: usize,
|
||||
input_index: usize,
|
||||
relative_pointer_value: u64,
|
||||
network: &Network,
|
||||
coinbase_txid: &TransactionIdentifier,
|
||||
coinbase_tx: &BitcoinTransactionData,
|
||||
coinbase_subsidy: u64,
|
||||
cumulated_fees: &mut u64,
|
||||
ctx: &Context,
|
||||
@@ -90,7 +89,6 @@ pub fn compute_satpoint_post_transfer(
|
||||
.collect::<_>();
|
||||
let outputs = tx.metadata.outputs.iter().map(|o| o.value).collect::<_>();
|
||||
let post_transfer_data = compute_next_satpoint_data(
|
||||
tx_index,
|
||||
input_index,
|
||||
&inputs,
|
||||
&outputs,
|
||||
@@ -141,10 +139,33 @@ pub fn compute_satpoint_post_transfer(
|
||||
SatPosition::Fee(offset) => {
|
||||
// Get Coinbase TX
|
||||
let total_offset = coinbase_subsidy + *cumulated_fees + offset;
|
||||
let outpoint = format_outpoint_to_watch(&coinbase_txid, 0);
|
||||
let outputs = coinbase_tx.metadata.outputs.iter().map(|o| o.value).collect();
|
||||
let post_transfer_data = compute_next_satpoint_data(
|
||||
0,
|
||||
&vec![total_offset],
|
||||
&outputs,
|
||||
total_offset,
|
||||
Some(ctx),
|
||||
);
|
||||
|
||||
// Identify the correct output
|
||||
let (output_index, offset) = match post_transfer_data {
|
||||
SatPosition::Output(pos) => pos,
|
||||
_ => {
|
||||
ctx.try_log(|logger| {
|
||||
info!(
|
||||
logger,
|
||||
"unable to locate satoshi in coinbase outputs",
|
||||
)
|
||||
});
|
||||
(0, total_offset)
|
||||
}
|
||||
};
|
||||
|
||||
let outpoint = format_outpoint_to_watch(&coinbase_tx.transaction_identifier, output_index);
|
||||
(
|
||||
outpoint,
|
||||
total_offset,
|
||||
offset,
|
||||
OrdinalInscriptionTransferDestination::SpentInFees,
|
||||
None,
|
||||
)
|
||||
@@ -163,7 +184,7 @@ pub fn augment_transaction_with_ordinals_transfers_data(
|
||||
tx: &mut BitcoinTransactionData,
|
||||
tx_index: usize,
|
||||
network: &Network,
|
||||
coinbase_txid: &TransactionIdentifier,
|
||||
coinbase_tx: &BitcoinTransactionData,
|
||||
coinbase_subsidy: u64,
|
||||
cumulated_fees: &mut u64,
|
||||
inscriptions_db_tx: &Transaction,
|
||||
@@ -203,11 +224,10 @@ pub fn augment_transaction_with_ordinals_transfers_data(
|
||||
let (destination, satpoint_post_transfer, post_transfer_output_value) =
|
||||
compute_satpoint_post_transfer(
|
||||
&&*tx,
|
||||
tx_index,
|
||||
input_index,
|
||||
watched_satpoint.offset,
|
||||
network,
|
||||
coinbase_txid,
|
||||
coinbase_tx,
|
||||
coinbase_subsidy,
|
||||
cumulated_fees,
|
||||
ctx,
|
||||
|
||||
@@ -105,14 +105,10 @@ pub async fn scan_bitcoin_chainstate_via_rpc_using_predicate(
|
||||
BitcoinPredicateType::OrdinalsProtocol(OrdinalOperations::InscriptionFeed(
|
||||
ref feed_data,
|
||||
)) if feed_data.meta_protocols.is_some() => {
|
||||
if current_block_height >= brc20_activation_height(&bitcoin_config.network) {
|
||||
Some(open_readonly_brc20_db_conn(
|
||||
&config.expected_cache_path(),
|
||||
ctx,
|
||||
)?)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
Some(open_readonly_brc20_db_conn(
|
||||
&config.expected_cache_path(),
|
||||
ctx,
|
||||
)?)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
@@ -156,7 +152,7 @@ pub async fn scan_bitcoin_chainstate_via_rpc_using_predicate(
|
||||
&inscriptions_db_tx,
|
||||
true,
|
||||
brc20_db_conn.as_ref(),
|
||||
&Context::empty(),
|
||||
&ctx,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@ pub mod observers;
|
||||
mod runloops;
|
||||
|
||||
use crate::config::{Config, PredicatesApi};
|
||||
use crate::core::meta_protocols::brc20::brc20_activation_height;
|
||||
use crate::core::meta_protocols::brc20::cache::Brc20MemoryCache;
|
||||
use crate::core::meta_protocols::brc20::db::open_readwrite_brc20_db_conn;
|
||||
use crate::core::meta_protocols::brc20::parser::ParsedBrc20Operation;
|
||||
use crate::core::meta_protocols::brc20::verifier::{
|
||||
verify_brc20_operation, verify_brc20_transfer, VerifiedBrc20Operation,
|
||||
};
|
||||
use crate::core::meta_protocols::brc20::brc20_activation_height;
|
||||
use crate::core::pipeline::download_and_pipeline_blocks;
|
||||
use crate::core::pipeline::processors::block_archiving::start_block_archiving_processor;
|
||||
use crate::core::pipeline::processors::inscription_indexing::process_block;
|
||||
@@ -47,7 +47,10 @@ use chainhook_sdk::observer::{
|
||||
start_event_observer, BitcoinBlockDataCached, DataHandlerEvent, EventObserverConfig,
|
||||
HandleBlock, ObserverCommand, ObserverEvent, ObserverSidecar,
|
||||
};
|
||||
use chainhook_sdk::types::{BitcoinBlockData, BlockIdentifier, OrdinalOperation};
|
||||
use chainhook_sdk::types::{
|
||||
BitcoinBlockData, BlockIdentifier, Brc20BalanceData, Brc20Operation, Brc20TokenDeployData,
|
||||
Brc20TransferData, OrdinalOperation,
|
||||
};
|
||||
use chainhook_sdk::utils::{BlockHeights, Context};
|
||||
use crossbeam_channel::unbounded;
|
||||
use crossbeam_channel::{select, Sender};
|
||||
@@ -857,7 +860,7 @@ pub fn chainhook_sidecar_mutate_blocks(
|
||||
}
|
||||
|
||||
pub fn write_brc20_block_operations(
|
||||
block: &BitcoinBlockData,
|
||||
block: &mut BitcoinBlockData,
|
||||
brc20_operation_map: &mut HashMap<String, ParsedBrc20Operation>,
|
||||
brc20_cache: &mut Brc20MemoryCache,
|
||||
db_tx: &Transaction,
|
||||
@@ -866,7 +869,7 @@ pub fn write_brc20_block_operations(
|
||||
if block.block_identifier.index < brc20_activation_height(&block.metadata.network) {
|
||||
return;
|
||||
}
|
||||
for (tx_index, tx) in block.transactions.iter().enumerate() {
|
||||
for (tx_index, tx) in block.transactions.iter_mut().enumerate() {
|
||||
for op in tx.metadata.ordinal_operations.iter() {
|
||||
match op {
|
||||
OrdinalOperation::InscriptionRevealed(reveal) => {
|
||||
@@ -882,68 +885,121 @@ pub fn write_brc20_block_operations(
|
||||
&db_tx,
|
||||
&ctx,
|
||||
) {
|
||||
Ok(op) => {
|
||||
match op {
|
||||
VerifiedBrc20Operation::TokenDeploy(token) => {
|
||||
brc20_cache.insert_token_deploy(
|
||||
&token,
|
||||
reveal,
|
||||
&block.block_identifier,
|
||||
tx_index as u64,
|
||||
db_tx,
|
||||
ctx,
|
||||
);
|
||||
ctx.try_log(|logger| {
|
||||
info!(
|
||||
logger,
|
||||
"BRC-20 deploy {} ({}) at block {}",
|
||||
token.tick,
|
||||
token.address,
|
||||
block.block_identifier.index
|
||||
)
|
||||
});
|
||||
}
|
||||
VerifiedBrc20Operation::TokenMint(balance) => {
|
||||
brc20_cache.insert_token_mint(
|
||||
&balance,
|
||||
reveal,
|
||||
&block.block_identifier,
|
||||
tx_index as u64,
|
||||
db_tx,
|
||||
ctx,
|
||||
);
|
||||
ctx.try_log(|logger| {
|
||||
info!(
|
||||
Ok(op) => match op {
|
||||
VerifiedBrc20Operation::TokenDeploy(token) => {
|
||||
let dec = token.dec as usize;
|
||||
tx.metadata.brc20_operation =
|
||||
Some(Brc20Operation::Deploy(Brc20TokenDeployData {
|
||||
tick: token.tick.clone(),
|
||||
max: format!(
|
||||
"{:.precision$}",
|
||||
token.max,
|
||||
precision = dec
|
||||
),
|
||||
lim: format!(
|
||||
"{:.precision$}",
|
||||
token.lim,
|
||||
precision = dec
|
||||
),
|
||||
dec: token.dec.to_string(),
|
||||
address: token.address.clone(),
|
||||
inscription_id: reveal.inscription_id.clone(),
|
||||
self_mint: token.self_mint,
|
||||
}));
|
||||
brc20_cache.insert_token_deploy(
|
||||
&token,
|
||||
reveal,
|
||||
&block.block_identifier,
|
||||
tx_index as u64,
|
||||
db_tx,
|
||||
ctx,
|
||||
);
|
||||
ctx.try_log(|logger| {
|
||||
info!(
|
||||
logger,
|
||||
"BRC-20 mint {} {} ({}) at block {}",
|
||||
balance.tick, balance.amt, balance.address,
|
||||
"BRC-20 deploy {} ({}) at block {}",
|
||||
token.tick,
|
||||
token.address,
|
||||
block.block_identifier.index
|
||||
)
|
||||
});
|
||||
}
|
||||
VerifiedBrc20Operation::TokenTransfer(balance) => {
|
||||
brc20_cache.insert_token_transfer(
|
||||
&balance,
|
||||
reveal,
|
||||
&block.block_identifier,
|
||||
tx_index as u64,
|
||||
db_tx,
|
||||
ctx,
|
||||
);
|
||||
ctx.try_log(|logger| {
|
||||
info!(
|
||||
logger,
|
||||
"BRC-20 transfer {} {} ({}) at block {}",
|
||||
balance.tick, balance.amt, balance.address,
|
||||
block.block_identifier.index
|
||||
)
|
||||
});
|
||||
}
|
||||
VerifiedBrc20Operation::TokenTransferSend(_) => {
|
||||
unreachable!("BRC-20 token transfer send should never be generated on reveal")
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
VerifiedBrc20Operation::TokenMint(balance) => {
|
||||
let Some(token) =
|
||||
brc20_cache.get_token(&balance.tick, db_tx, ctx)
|
||||
else {
|
||||
unreachable!();
|
||||
};
|
||||
tx.metadata.brc20_operation =
|
||||
Some(Brc20Operation::Mint(Brc20BalanceData {
|
||||
tick: balance.tick.clone(),
|
||||
amt: format!(
|
||||
"{:.precision$}",
|
||||
balance.amt,
|
||||
precision = token.dec as usize
|
||||
),
|
||||
address: balance.address.clone(),
|
||||
inscription_id: reveal.inscription_id.clone(),
|
||||
}));
|
||||
brc20_cache.insert_token_mint(
|
||||
&balance,
|
||||
reveal,
|
||||
&block.block_identifier,
|
||||
tx_index as u64,
|
||||
db_tx,
|
||||
ctx,
|
||||
);
|
||||
ctx.try_log(|logger| {
|
||||
info!(
|
||||
logger,
|
||||
"BRC-20 mint {} {} ({}) at block {}",
|
||||
balance.tick,
|
||||
balance.amt,
|
||||
balance.address,
|
||||
block.block_identifier.index
|
||||
)
|
||||
});
|
||||
}
|
||||
VerifiedBrc20Operation::TokenTransfer(balance) => {
|
||||
let Some(token) =
|
||||
brc20_cache.get_token(&balance.tick, db_tx, ctx)
|
||||
else {
|
||||
unreachable!();
|
||||
};
|
||||
tx.metadata.brc20_operation =
|
||||
Some(Brc20Operation::Transfer(Brc20BalanceData {
|
||||
tick: balance.tick.clone(),
|
||||
amt: format!(
|
||||
"{:.precision$}",
|
||||
balance.amt,
|
||||
precision = token.dec as usize
|
||||
),
|
||||
address: balance.address.clone(),
|
||||
inscription_id: reveal.inscription_id.clone(),
|
||||
}));
|
||||
brc20_cache.insert_token_transfer(
|
||||
&balance,
|
||||
reveal,
|
||||
&block.block_identifier,
|
||||
tx_index as u64,
|
||||
db_tx,
|
||||
ctx,
|
||||
);
|
||||
ctx.try_log(|logger| {
|
||||
info!(
|
||||
logger,
|
||||
"BRC-20 transfer {} {} ({}) at block {}",
|
||||
balance.tick,
|
||||
balance.amt,
|
||||
balance.address,
|
||||
block.block_identifier.index
|
||||
)
|
||||
});
|
||||
}
|
||||
VerifiedBrc20Operation::TokenTransferSend(_) => {
|
||||
unreachable!("BRC-20 token transfer send should never be generated on reveal")
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
ctx.try_log(|logger| {
|
||||
debug!(logger, "Error validating BRC-20 operation {}", e)
|
||||
@@ -957,6 +1013,28 @@ pub fn write_brc20_block_operations(
|
||||
OrdinalOperation::InscriptionTransferred(transfer) => {
|
||||
match verify_brc20_transfer(transfer, brc20_cache, &db_tx, &ctx) {
|
||||
Ok(data) => {
|
||||
let Some(token) = brc20_cache.get_token(&data.tick, db_tx, ctx) else {
|
||||
unreachable!();
|
||||
};
|
||||
let Some(unsent_transfer) = brc20_cache.get_unsent_token_transfer(
|
||||
transfer.ordinal_number,
|
||||
db_tx,
|
||||
ctx,
|
||||
) else {
|
||||
unreachable!();
|
||||
};
|
||||
tx.metadata.brc20_operation =
|
||||
Some(Brc20Operation::TransferSend(Brc20TransferData {
|
||||
tick: data.tick.clone(),
|
||||
amt: format!(
|
||||
"{:.precision$}",
|
||||
data.amt * -1.0,
|
||||
precision = token.dec as usize
|
||||
),
|
||||
sender_address: data.sender_address.clone(),
|
||||
receiver_address: data.receiver_address.clone(),
|
||||
inscription_id: unsent_transfer.inscription_id,
|
||||
}));
|
||||
brc20_cache.insert_token_transfer_send(
|
||||
&data,
|
||||
&transfer,
|
||||
@@ -969,7 +1047,10 @@ pub fn write_brc20_block_operations(
|
||||
info!(
|
||||
logger,
|
||||
"BRC-20 transfer_send {} {} ({} -> {}) at block {}",
|
||||
data.tick, data.amt, data.sender_address, data.receiver_address,
|
||||
data.tick,
|
||||
data.amt,
|
||||
data.sender_address,
|
||||
data.receiver_address,
|
||||
block.block_identifier.index
|
||||
)
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user