diff --git a/src/index/updater.rs b/src/index/updater.rs index 6c4de37267..316f847900 100644 --- a/src/index/updater.rs +++ b/src/index/updater.rs @@ -1,3 +1,4 @@ +use crate::okx::datastore::ord::InscriptionOp; use crate::okx::protocol::{context::Context, BlockContext, ProtocolConfig, ProtocolManager}; use std::sync::atomic::{AtomicUsize, Ordering}; use { @@ -332,17 +333,15 @@ impl<'index> Updater<'_> { Ok((outpoint_sender, tx_out_receiver)) } - fn index_block( + fn index_block_ord( &mut self, index: &Index, outpoint_sender: &mut Sender, tx_out_receiver: &mut Receiver, wtx: &mut WriteTransaction, - block: BlockData, + block: &BlockData, tx_out_cache: &mut SimpleLru, - ) -> Result<()> { - Reorg::detect_reorg(&block, self.height, self.index)?; - + ) -> Result>> { let start = Instant::now(); let mut sat_ranges_written = 0; let mut outputs_in_block = 0; @@ -620,32 +619,6 @@ impl<'index> Updater<'_> { inscription_updater.flush_cache()?; - let mut context = Context { - chain: BlockContext { - network: index.get_chain_network(), - blockheight: self.height, - blocktime: block.header.time, - }, - tx_out_cache, - hit: 0, - miss: 0, - ORD_TX_TO_OPERATIONS: &mut wtx.open_table(ORD_TX_TO_OPERATIONS)?, - COLLECTIONS_KEY_TO_INSCRIPTION_ID: &mut wtx.open_table(COLLECTIONS_KEY_TO_INSCRIPTION_ID)?, - COLLECTIONS_INSCRIPTION_ID_TO_KINDS: &mut wtx - .open_table(COLLECTIONS_INSCRIPTION_ID_TO_KINDS)?, - SEQUENCE_NUMBER_TO_INSCRIPTION_ENTRY: &mut sequence_number_to_inscription_entry, - OUTPOINT_TO_ENTRY: &mut outpoint_to_entry, - BRC20_BALANCES: &mut wtx.open_table(BRC20_BALANCES)?, - BRC20_TOKEN: &mut wtx.open_table(BRC20_TOKEN)?, - BRC20_EVENTS: &mut wtx.open_table(BRC20_EVENTS)?, - BRC20_TRANSFERABLELOG: &mut wtx.open_table(BRC20_TRANSFERABLELOG)?, - BRC20_INSCRIBE_TRANSFER: &mut wtx.open_table(BRC20_INSCRIBE_TRANSFER)?, - }; - - // Create a protocol manager to index the block of bitmap data. - let config = ProtocolConfig::new_with_options(&index.options); - ProtocolManager::new(config).index_block(&mut context, &block, operations)?; - if index.index_runes && self.height >= self.index.options.first_rune_height() { let mut outpoint_to_rune_balances = wtx.open_table(OUTPOINT_TO_RUNE_BALANCES)?; let mut rune_id_to_rune_entry = wtx.open_table(RUNE_ID_TO_RUNE_ENTRY)?; @@ -695,17 +668,71 @@ impl<'index> Updater<'_> { height_to_block_header.insert(&self.height, &block.header.store())?; - self.height += 1; self.outputs_traversed += outputs_in_block; log::info!( - "Wrote {sat_ranges_written} sat ranges from {outputs_in_block} outputs in {}/{} ms, hit miss: {}/{}", + "Wrote {sat_ranges_written} sat ranges from {outputs_in_block} outputs in {}/{} ms.", ord_cost, (Instant::now() - start).as_millis(), - context.hit, - context.miss, ); + Ok(operations) + } + + fn index_block( + &mut self, + index: &Index, + outpoint_sender: &mut Sender, + tx_out_receiver: &mut Receiver, + wtx: &mut WriteTransaction, + block: BlockData, + tx_out_cache: &mut SimpleLru, + ) -> Result<()> { + Reorg::detect_reorg(&block, self.height, self.index)?; + + let operations = self.index_block_ord( + index, + outpoint_sender, + tx_out_receiver, + wtx, + &block, + tx_out_cache, + )?; + + let mut context = Context { + chain: BlockContext { + network: index.get_chain_network(), + blockheight: self.height, + blocktime: block.header.time, + }, + tx_out_cache, + hit: 0, + miss: 0, + save_cost: 0, + resolve_cost: 0, + execute_cost: 0, + inscriptions_size: 0, + messages_size: 0, + ORD_TX_TO_OPERATIONS: &mut wtx.open_table(ORD_TX_TO_OPERATIONS)?, + COLLECTIONS_KEY_TO_INSCRIPTION_ID: &mut wtx.open_table(COLLECTIONS_KEY_TO_INSCRIPTION_ID)?, + COLLECTIONS_INSCRIPTION_ID_TO_KINDS: &mut wtx + .open_table(COLLECTIONS_INSCRIPTION_ID_TO_KINDS)?, + SEQUENCE_NUMBER_TO_INSCRIPTION_ENTRY: &mut wtx + .open_table(SEQUENCE_NUMBER_TO_INSCRIPTION_ENTRY)?, + OUTPOINT_TO_ENTRY: &mut wtx.open_table(OUTPOINT_TO_ENTRY)?, + BRC20_BALANCES: &mut wtx.open_table(BRC20_BALANCES)?, + BRC20_TOKEN: &mut wtx.open_table(BRC20_TOKEN)?, + BRC20_EVENTS: &mut wtx.open_table(BRC20_EVENTS)?, + BRC20_TRANSFERABLELOG: &mut wtx.open_table(BRC20_TRANSFERABLELOG)?, + BRC20_INSCRIBE_TRANSFER: &mut wtx.open_table(BRC20_INSCRIBE_TRANSFER)?, + }; + + // Create a protocol manager to index the block of bitmap data. + let config = ProtocolConfig::new_with_options(&index.options); + ProtocolManager::new(config).index_block(&mut context, &block, operations)?; + + self.height += 1; + Ok(()) } diff --git a/src/okx/protocol/context.rs b/src/okx/protocol/context.rs index 1d88af5478..757e304ec9 100644 --- a/src/okx/protocol/context.rs +++ b/src/okx/protocol/context.rs @@ -33,6 +33,11 @@ pub struct Context<'a, 'db, 'txn> { pub(crate) tx_out_cache: &'a mut SimpleLru, pub(crate) hit: u64, pub(crate) miss: u64, + pub(crate) save_cost: u128, + pub(crate) resolve_cost: u128, + pub(crate) execute_cost: u128, + pub(crate) inscriptions_size: usize, + pub(crate) messages_size: usize, // ord tables pub(crate) ORD_TX_TO_OPERATIONS: &'a mut Table<'db, 'txn, &'static TxidValue, &'static [u8]>, diff --git a/src/okx/protocol/protocol_manager.rs b/src/okx/protocol/protocol_manager.rs index b1541088bd..b519c7a060 100644 --- a/src/okx/protocol/protocol_manager.rs +++ b/src/okx/protocol/protocol_manager.rs @@ -1,5 +1,6 @@ use crate::okx::datastore::ord::OrdReaderWriter; use crate::okx::protocol::context::Context; +use bitcoin::Transaction; use { super::*, crate::{ @@ -27,6 +28,38 @@ impl ProtocolManager { } } + pub(crate) fn index_tx( + &self, + context: &mut Context, + tx: &Transaction, + txid: &Txid, + tx_operations: &Vec, + ) -> Result { + // save all transaction operations to ord database. + if self.config.enable_ord_receipts + && context.chain.blockheight >= self.config.first_inscription_height + { + let start = Instant::now(); + context.save_transaction_operations(txid, tx_operations)?; + context.inscriptions_size += tx_operations.len(); + context.save_cost += start.elapsed().as_micros(); + } + + let start = Instant::now(); + // Resolve and execute messages. + let messages = self + .resolve_man + .resolve_message(context, tx, tx_operations)?; + context.resolve_cost += start.elapsed().as_micros(); + + let start = Instant::now(); + self.call_man.execute_message(context, txid, &messages)?; + context.execute_cost += start.elapsed().as_micros(); + context.messages_size += messages.len(); + + Ok(()) + } + pub(crate) fn index_block( &self, context: &mut Context, @@ -34,11 +67,7 @@ impl ProtocolManager { operations: HashMap>, ) -> Result { let start = Instant::now(); - let mut inscriptions_size = 0; - let mut messages_size = 0; - let mut cost1 = 0u128; - let mut cost2 = 0u128; - let mut cost3 = 0u128; + // skip the coinbase transaction. for (tx, txid) in block.txdata.iter() { // skip coinbase transaction. @@ -52,27 +81,7 @@ impl ProtocolManager { // index inscription operations. if let Some(tx_operations) = operations.get(txid) { - // save all transaction operations to ord database. - if self.config.enable_ord_receipts - && context.chain.blockheight >= self.config.first_inscription_height - { - let start = Instant::now(); - context.save_transaction_operations(txid, tx_operations)?; - inscriptions_size += tx_operations.len(); - cost1 += start.elapsed().as_micros(); - } - - let start = Instant::now(); - // Resolve and execute messages. - let messages = self - .resolve_man - .resolve_message(context, tx, tx_operations)?; - cost2 += start.elapsed().as_micros(); - - let start = Instant::now(); - self.call_man.execute_message(context, txid, &messages)?; - cost3 += start.elapsed().as_micros(); - messages_size += messages.len(); + self.index_tx(context, tx, txid, tx_operations)?; } } @@ -81,19 +90,21 @@ impl ProtocolManager { if self.config.enable_index_bitmap { bitmap_count = ord_proto::bitmap::index_bitmap(context, &operations)?; } - let cost4 = bitmap_start.elapsed().as_millis(); + let bitmap_cost = bitmap_start.elapsed().as_millis(); log::info!( - "Protocol Manager indexed block {} with ord inscriptions {}, messages {}, bitmap {} in {} ms, {}/{}/{}/{}", + "Protocol Manager indexed block {} with ord inscriptions {}, messages {}, bitmap {} in {} ms, {}/{}/{}/{}, hit/miss {}/{}", context.chain.blockheight, - inscriptions_size, - messages_size, + context.inscriptions_size, + context.messages_size, bitmap_count, start.elapsed().as_millis(), - cost1/1000, - cost2/1000, - cost3/1000, - cost4, + context.save_cost/1000, + context.resolve_cost/1000, + context.execute_cost/1000, + bitmap_cost, + context.hit, + context.miss, ); Ok(()) }