From abe51e1ede5b0ea6887723d28c3b3d418ce6fec2 Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Mon, 6 Jan 2025 17:22:45 +0100 Subject: [PATCH 1/6] added txindex infrastructure for tracking transactions --- stackslib/src/chainstate/coordinator/mod.rs | 7 +- .../chainstate/nakamoto/coordinator/mod.rs | 1 + .../chainstate/nakamoto/coordinator/tests.rs | 96 ++++++++++++++++++- stackslib/src/chainstate/nakamoto/mod.rs | 51 ++++++++++ stackslib/src/chainstate/nakamoto/shadow.rs | 1 + .../src/chainstate/nakamoto/tests/node.rs | 7 +- stackslib/src/chainstate/stacks/db/mod.rs | 10 +- stackslib/src/config/mod.rs | 11 +++ testnet/stacks-node/src/run_loop/nakamoto.rs | 1 + testnet/stacks-node/src/run_loop/neon.rs | 1 + 10 files changed, 172 insertions(+), 14 deletions(-) diff --git a/stackslib/src/chainstate/coordinator/mod.rs b/stackslib/src/chainstate/coordinator/mod.rs index 122aedbefb..4e12bf98a4 100644 --- a/stackslib/src/chainstate/coordinator/mod.rs +++ b/stackslib/src/chainstate/coordinator/mod.rs @@ -207,6 +207,9 @@ pub struct ChainsCoordinatorConfig { /// true: always wait for canonical anchor blocks, even if it stalls the chain /// false: proceed to process new chain history even if we're missing an anchor block. pub require_affirmed_anchor_blocks: bool, + /// true: enable transactions indexing + /// false: no transactions indexing + pub txindex: bool, } impl ChainsCoordinatorConfig { @@ -215,6 +218,7 @@ impl ChainsCoordinatorConfig { always_use_affirmation_maps: true, require_affirmed_anchor_blocks: true, assume_present_anchor_blocks: true, + txindex: false, } } @@ -223,6 +227,7 @@ impl ChainsCoordinatorConfig { always_use_affirmation_maps: false, require_affirmed_anchor_blocks: false, assume_present_anchor_blocks: false, + txindex: false, } } } @@ -248,7 +253,7 @@ pub struct ChainsCoordinator< pub reward_set_provider: R, pub notifier: N, pub atlas_config: AtlasConfig, - config: ChainsCoordinatorConfig, + pub config: ChainsCoordinatorConfig, burnchain_indexer: B, /// Used to tell the P2P thread that the stackerdb /// needs to be refreshed. diff --git a/stackslib/src/chainstate/nakamoto/coordinator/mod.rs b/stackslib/src/chainstate/nakamoto/coordinator/mod.rs index c6dd44ac39..b23427d438 100644 --- a/stackslib/src/chainstate/nakamoto/coordinator/mod.rs +++ b/stackslib/src/chainstate/nakamoto/coordinator/mod.rs @@ -801,6 +801,7 @@ impl< &mut self.sortition_db, &canonical_sortition_tip, self.dispatcher, + self.config.txindex, ) { Ok(receipt_opt) => receipt_opt, Err(ChainstateError::InvalidStacksBlock(msg)) => { diff --git a/stackslib/src/chainstate/nakamoto/coordinator/tests.rs b/stackslib/src/chainstate/nakamoto/coordinator/tests.rs index e0b3375452..8a770f931e 100644 --- a/stackslib/src/chainstate/nakamoto/coordinator/tests.rs +++ b/stackslib/src/chainstate/nakamoto/coordinator/tests.rs @@ -34,7 +34,7 @@ use stacks_common::types::chainstate::{ BurnchainHeaderHash, StacksAddress, StacksBlockId, StacksPrivateKey, StacksPublicKey, }; use stacks_common::types::{Address, StacksEpoch, StacksEpochId, StacksPublicKeyBuffer}; -use stacks_common::util::hash::Hash160; +use stacks_common::util::hash::{to_hex, Hash160}; use stacks_common::util::secp256k1::Secp256k1PrivateKey; use stacks_common::util::vrf::VRFProof; @@ -1436,7 +1436,7 @@ fn pox_treatment() { false }, ); - let processing_result = peer.try_process_block(&invalid_block).unwrap_err(); + let processing_result = peer.try_process_block(&invalid_block, false).unwrap_err(); assert_eq!( processing_result.to_string(), "Bitvec does not match the block commit's PoX handling".to_string(), @@ -1527,7 +1527,7 @@ fn pox_treatment() { false }, ); - let processing_result = peer.try_process_block(&invalid_block).unwrap_err(); + let processing_result = peer.try_process_block(&invalid_block, false).unwrap_err(); assert_eq!( processing_result.to_string(), "Bitvec does not match the block commit's PoX handling".to_string(), @@ -1575,6 +1575,96 @@ fn pox_treatment() { ); } +#[test] +// Test Transactions indexing system +fn transactions_indexing() { + let private_key = StacksPrivateKey::from_seed(&[2]); + let addr = StacksAddress::p2pkh(false, &StacksPublicKey::from_private(&private_key)); + + let num_stackers: u32 = 4; + let mut signing_key_seed = num_stackers.to_be_bytes().to_vec(); + signing_key_seed.extend_from_slice(&[1, 1, 1, 1]); + let signing_key = StacksPrivateKey::from_seed(signing_key_seed.as_slice()); + let test_stackers = (0..num_stackers) + .map(|index| TestStacker { + signer_private_key: signing_key.clone(), + stacker_private_key: StacksPrivateKey::from_seed(&index.to_be_bytes()), + amount: u64::MAX as u128 - 10000, + pox_addr: Some(PoxAddress::Standard( + StacksAddress::new( + C32_ADDRESS_VERSION_TESTNET_SINGLESIG, + Hash160::from_data(&index.to_be_bytes()), + ), + Some(AddressHashMode::SerializeP2PKH), + )), + max_amount: None, + }) + .collect::>(); + let test_signers = TestSigners::new(vec![signing_key]); + let mut pox_constants = TestPeerConfig::default().burnchain.pox_constants; + pox_constants.reward_cycle_length = 10; + pox_constants.v2_unlock_height = 21; + pox_constants.pox_3_activation_height = 26; + pox_constants.v3_unlock_height = 27; + pox_constants.pox_4_activation_height = 28; + + let mut boot_plan = NakamotoBootPlan::new(function_name!()) + .with_test_stackers(test_stackers.clone()) + .with_test_signers(test_signers.clone()) + .with_private_key(private_key); + boot_plan.pox_constants = pox_constants; + + let mut peer = boot_plan.boot_into_nakamoto_peer(vec![], None); + + // generate a new block with txindex + let (tracked_block, burn_height, ..) = + peer.single_block_tenure(&private_key, |_| {}, |_| {}, |_| false); + + assert_eq!(peer.try_process_block(&tracked_block, true).unwrap(), true); + + let tracked_block_id = tracked_block.block_id(); + + // generate a new block but without txindex + let (untracked_block, burn_height, ..) = + peer.single_block_tenure(&private_key, |_| {}, |_| {}, |_| false); + + assert_eq!( + peer.try_process_block(&untracked_block, false).unwrap(), + true + ); + + let untracked_block_id = untracked_block.block_id(); + + let chainstate = &peer.stacks_node.unwrap().chainstate; + + // compare transactions to what has been tracked + for tx in tracked_block.txs { + let current_tx_hex = to_hex(&tx.serialize_to_vec()); + let (index_block_hash, tx_hex) = + NakamotoChainState::get_index_block_hash_and_tx_hex_from_txid( + &chainstate.index_conn(), + tx.txid(), + ) + .unwrap() + .unwrap(); + assert_eq!(index_block_hash, tracked_block_id); + assert_eq!(tx_hex, current_tx_hex); + } + + // ensure untracked transactions are not recorded + for tx in untracked_block.txs { + assert_eq!( + NakamotoChainState::get_index_block_hash_and_tx_hex_from_txid( + &chainstate.index_conn(), + tx.txid(), + ) + .unwrap() + .is_none(), + true + ); + } +} + /// Test chainstate getters against an instantiated epoch2/Nakamoto chain. /// There are 11 epoch2 blocks and 2 nakamto tenure with 10 nakamoto blocks each /// Tests: diff --git a/stackslib/src/chainstate/nakamoto/mod.rs b/stackslib/src/chainstate/nakamoto/mod.rs index 5f30ac51fc..cc077473b1 100644 --- a/stackslib/src/chainstate/nakamoto/mod.rs +++ b/stackslib/src/chainstate/nakamoto/mod.rs @@ -1869,6 +1869,7 @@ impl NakamotoChainState { sort_db: &mut SortitionDB, canonical_sortition_tip: &SortitionId, dispatcher_opt: Option<&T>, + txindex: bool, ) -> Result, ChainstateError> { #[cfg(test)] fault_injection::stall_block_processing(); @@ -2162,6 +2163,20 @@ impl NakamotoChainState { tx_receipts.push(unlock_receipt); } + // if txindex is enabled, let's record each transaction in the transactions table + if txindex { + let block_id = next_ready_block.block_id(); + let stacks_db_tx = stacks_chain_state.index_tx_begin(); + for tx_receipt in tx_receipts.iter() { + Self::record_transaction(&stacks_db_tx, &block_id, tx_receipt); + } + + let commit = stacks_db_tx.commit(); + if commit.is_err() { + warn!("Could not index transactions: {}", commit.err().unwrap()); + } + } + // announce the block, if we're connected to an event dispatcher if let Some(dispatcher) = dispatcher_opt { let block_event = ( @@ -3539,6 +3554,42 @@ impl NakamotoChainState { Ok(()) } + // Index a transaction in the transactions table (used by the lagacy STACKS_TRANSACTION_LOG and txindex) + pub fn record_transaction( + stacks_db_tx: &StacksDBTx, + block_id: &StacksBlockId, + tx_receipt: &StacksTransactionReceipt, + ) { + let insert = + "INSERT INTO transactions (txid, index_block_hash, tx_hex, result) VALUES (?, ?, ?, ?)"; + let txid = tx_receipt.transaction.txid(); + let tx_hex = tx_receipt.transaction.serialize_to_dbstring(); + let result = tx_receipt.result.to_string(); + let params = params![txid, block_id, tx_hex, result]; + if let Err(e) = stacks_db_tx.execute(insert, params) { + warn!("Failed to record TX: {}", e); + } + } + + // Get index_block_hash and transaction payload hex by txid from the transactions table + pub fn get_index_block_hash_and_tx_hex_from_txid( + conn: &Connection, + txid: Txid, + ) -> Result, ChainstateError> { + let sql = "SELECT index_block_hash, tx_hex FROM transactions WHERE txid = ?"; + let args = params![txid]; + + let mut stmt = conn.prepare(sql)?; + Ok(stmt + .query_row(args, |row| { + let index_block_hash: StacksBlockId = row.get(0)?; + let tx_hex: String = row.get(1)?; + + Ok((index_block_hash, tx_hex)) + }) + .optional()?) + } + /// Fetch number of blocks signed for a given signer and reward cycle /// This is the data tracked by `record_block_signers()` pub fn get_signer_block_count( diff --git a/stackslib/src/chainstate/nakamoto/shadow.rs b/stackslib/src/chainstate/nakamoto/shadow.rs index dad10f62e0..13f24c5e36 100644 --- a/stackslib/src/chainstate/nakamoto/shadow.rs +++ b/stackslib/src/chainstate/nakamoto/shadow.rs @@ -898,6 +898,7 @@ pub fn process_shadow_block( sort_db, &sort_tip.sortition_id, no_dispatch.as_ref(), + false, ) { Ok(receipt_opt) => receipt_opt, Err(ChainstateError::InvalidStacksBlock(msg)) => { diff --git a/stackslib/src/chainstate/nakamoto/tests/node.rs b/stackslib/src/chainstate/nakamoto/tests/node.rs index cd21c7eeaa..8cd9fcd3ea 100644 --- a/stackslib/src/chainstate/nakamoto/tests/node.rs +++ b/stackslib/src/chainstate/nakamoto/tests/node.rs @@ -1384,7 +1384,11 @@ impl TestPeer<'_> { proof } - pub fn try_process_block(&mut self, block: &NakamotoBlock) -> Result { + pub fn try_process_block( + &mut self, + block: &NakamotoBlock, + txindex: bool, + ) -> Result { let mut sort_handle = self.sortdb.as_ref().unwrap().index_handle_at_tip(); let stacks_tip = sort_handle.get_nakamoto_tip_block_id().unwrap().unwrap(); let accepted = Relayer::process_new_nakamoto_block( @@ -1407,6 +1411,7 @@ impl TestPeer<'_> { self.sortdb.as_mut().unwrap(), &sort_tip, None, + txindex, )? else { return Ok(false); diff --git a/stackslib/src/chainstate/stacks/db/mod.rs b/stackslib/src/chainstate/stacks/db/mod.rs index 31159137ac..aa292750da 100644 --- a/stackslib/src/chainstate/stacks/db/mod.rs +++ b/stackslib/src/chainstate/stacks/db/mod.rs @@ -643,16 +643,8 @@ impl<'a> ChainstateTx<'a> { events: &[StacksTransactionReceipt], ) { if *TRANSACTION_LOG { - let insert = - "INSERT INTO transactions (txid, index_block_hash, tx_hex, result) VALUES (?, ?, ?, ?)"; for tx_event in events.iter() { - let txid = tx_event.transaction.txid(); - let tx_hex = tx_event.transaction.serialize_to_dbstring(); - let result = tx_event.result.to_string(); - let params = params![txid, block_id, tx_hex, result]; - if let Err(e) = self.tx.tx().execute(insert, params) { - warn!("Failed to log TX: {}", e); - } + NakamotoChainState::record_transaction(&self.tx, block_id, tx_event); } } for tx_event in events.iter() { diff --git a/stackslib/src/config/mod.rs b/stackslib/src/config/mod.rs index f1b41b803a..c8bbfc5dd4 100644 --- a/stackslib/src/config/mod.rs +++ b/stackslib/src/config/mod.rs @@ -41,6 +41,7 @@ use crate::burnchains::bitcoin::BitcoinNetworkType; use crate::burnchains::{Burnchain, MagicBytes, PoxConstants, BLOCKSTACK_MAGIC_MAINNET}; use crate::chainstate::nakamoto::signer_set::NakamotoSigners; use crate::chainstate::stacks::boot::MINERS_NAME; +use crate::chainstate::stacks::db::TRANSACTION_LOG; use crate::chainstate::stacks::index::marf::MARFOpenOpts; use crate::chainstate::stacks::index::storage::TrieHashCalculationMode; use crate::chainstate::stacks::miner::{BlockBuilderSettings, MinerStatus}; @@ -1661,6 +1662,8 @@ pub struct NodeConfig { pub chain_liveness_poll_time_secs: u64, /// stacker DBs we replicate pub stacker_dbs: Vec, + /// enable transactions indexing + pub txindex: bool, } #[derive(Clone, Debug)] @@ -1939,6 +1942,7 @@ impl Default for NodeConfig { fault_injection_hide_blocks: false, chain_liveness_poll_time_secs: 300, stacker_dbs: vec![], + txindex: false, } } } @@ -2432,6 +2436,8 @@ pub struct NodeConfigFile { pub stacker_dbs: Option>, /// fault injection: fail to push blocks with this probability (0-100) pub fault_injection_block_push_fail_probability: Option, + /// enable transactions indexing + pub txindex: bool, } impl NodeConfigFile { @@ -2530,6 +2536,11 @@ impl NodeConfigFile { } else { default_node_config.fault_injection_block_push_fail_probability }, + txindex: if self.txindex && *TRANSACTION_LOG { + return Err("STACKS_TRANSACTION_LOG is deprecated and cannot be used with txindex.".to_string()); + } else { + self.txindex + }, }; Ok(node_config) } diff --git a/testnet/stacks-node/src/run_loop/nakamoto.rs b/testnet/stacks-node/src/run_loop/nakamoto.rs index 335fb325d8..2a2bb639ac 100644 --- a/testnet/stacks-node/src/run_loop/nakamoto.rs +++ b/testnet/stacks-node/src/run_loop/nakamoto.rs @@ -324,6 +324,7 @@ impl RunLoop { require_affirmed_anchor_blocks: moved_config .node .require_affirmed_anchor_blocks, + txindex: moved_config.node.txindex, }; ChainsCoordinator::run( coord_config, diff --git a/testnet/stacks-node/src/run_loop/neon.rs b/testnet/stacks-node/src/run_loop/neon.rs index 4ecc84b73b..594bfaed22 100644 --- a/testnet/stacks-node/src/run_loop/neon.rs +++ b/testnet/stacks-node/src/run_loop/neon.rs @@ -620,6 +620,7 @@ impl RunLoop { require_affirmed_anchor_blocks: moved_config .node .require_affirmed_anchor_blocks, + txindex: false, }; ChainsCoordinator::run( coord_config, From c23f0c907fbcfc5bc295c9fa24c03bc0a569610c Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Mon, 6 Jan 2025 17:46:14 +0100 Subject: [PATCH 2/6] fixed formatting --- stackslib/src/config/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/stackslib/src/config/mod.rs b/stackslib/src/config/mod.rs index c8bbfc5dd4..6bc85afaca 100644 --- a/stackslib/src/config/mod.rs +++ b/stackslib/src/config/mod.rs @@ -2537,7 +2537,10 @@ impl NodeConfigFile { default_node_config.fault_injection_block_push_fail_probability }, txindex: if self.txindex && *TRANSACTION_LOG { - return Err("STACKS_TRANSACTION_LOG is deprecated and cannot be used with txindex.".to_string()); + return Err( + "STACKS_TRANSACTION_LOG is deprecated and cannot be used with txindex." + .to_string(), + ); } else { self.txindex }, From 19be761bcf6ca1e2bfe7f4bf57aa4a29d30c5d03 Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Fri, 14 Feb 2025 15:42:28 +0100 Subject: [PATCH 3/6] removed TRANSACTION_LOG/STACKS_TRANSACTION_LOG --- stackslib/src/chainstate/nakamoto/mod.rs | 2 +- stackslib/src/chainstate/stacks/db/mod.rs | 10 ---------- stackslib/src/config/mod.rs | 11 ++--------- testnet/stacks-node/src/run_loop/neon.rs | 2 +- 4 files changed, 4 insertions(+), 21 deletions(-) diff --git a/stackslib/src/chainstate/nakamoto/mod.rs b/stackslib/src/chainstate/nakamoto/mod.rs index 825ac0a7d8..36e7cd8a3d 100644 --- a/stackslib/src/chainstate/nakamoto/mod.rs +++ b/stackslib/src/chainstate/nakamoto/mod.rs @@ -3534,7 +3534,7 @@ impl NakamotoChainState { Ok(()) } - // Index a transaction in the transactions table (used by the lagacy STACKS_TRANSACTION_LOG and txindex) + // Index a transaction in the transactions table (used by txindex) pub fn record_transaction( stacks_db_tx: &StacksDBTx, block_id: &StacksBlockId, diff --git a/stackslib/src/chainstate/stacks/db/mod.rs b/stackslib/src/chainstate/stacks/db/mod.rs index e491c8c5cb..0ea02d239d 100644 --- a/stackslib/src/chainstate/stacks/db/mod.rs +++ b/stackslib/src/chainstate/stacks/db/mod.rs @@ -97,11 +97,6 @@ pub mod headers; pub mod transactions; pub mod unconfirmed; -lazy_static! { - pub static ref TRANSACTION_LOG: bool = - std::env::var("STACKS_TRANSACTION_LOG") == Ok("1".into()); -} - /// Fault injection struct for various kinds of faults we'd like to introduce into the system pub struct StacksChainStateFaults { // if true, then the envar STACKS_HIDE_BLOCKS_AT_HEIGHT will be consulted to get a list of @@ -641,11 +636,6 @@ impl<'a> ChainstateTx<'a> { block_id: &StacksBlockId, events: &[StacksTransactionReceipt], ) { - if *TRANSACTION_LOG { - for tx_event in events.iter() { - NakamotoChainState::record_transaction(&self.tx, block_id, tx_event); - } - } for tx_event in events.iter() { let txid = tx_event.transaction.txid(); if let Err(e) = monitoring::log_transaction_processed(&txid, &self.root_path) { diff --git a/stackslib/src/config/mod.rs b/stackslib/src/config/mod.rs index c0f51a55bb..5384ea2fe2 100644 --- a/stackslib/src/config/mod.rs +++ b/stackslib/src/config/mod.rs @@ -41,7 +41,6 @@ use crate::burnchains::bitcoin::BitcoinNetworkType; use crate::burnchains::{Burnchain, MagicBytes, PoxConstants, BLOCKSTACK_MAGIC_MAINNET}; use crate::chainstate::nakamoto::signer_set::NakamotoSigners; use crate::chainstate::stacks::boot::MINERS_NAME; -use crate::chainstate::stacks::db::TRANSACTION_LOG; use crate::chainstate::stacks::index::marf::MARFOpenOpts; use crate::chainstate::stacks::index::storage::TrieHashCalculationMode; use crate::chainstate::stacks::miner::{BlockBuilderSettings, MinerStatus}; @@ -2576,14 +2575,8 @@ impl NodeConfigFile { } else { default_node_config.fault_injection_block_push_fail_probability }, - txindex: if self.txindex && *TRANSACTION_LOG { - return Err( - "STACKS_TRANSACTION_LOG is deprecated and cannot be used with txindex." - .to_string(), - ); - } else { - self.txindex - }, + + txindex: self.txindex, }; Ok(node_config) } diff --git a/testnet/stacks-node/src/run_loop/neon.rs b/testnet/stacks-node/src/run_loop/neon.rs index 6605a00049..0fe2cec772 100644 --- a/testnet/stacks-node/src/run_loop/neon.rs +++ b/testnet/stacks-node/src/run_loop/neon.rs @@ -657,7 +657,7 @@ impl RunLoop { require_affirmed_anchor_blocks: moved_config .node .require_affirmed_anchor_blocks, - txindex: false, + txindex: moved_config.node.txindex, }; ChainsCoordinator::run( coord_config, From ad7a88bfe899d3ecf5ed4cb4b87eabafc7b54167 Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Fri, 14 Feb 2025 15:45:55 +0100 Subject: [PATCH 4/6] removed block_id from log_transactions_processed --- stackslib/src/chainstate/nakamoto/mod.rs | 2 +- stackslib/src/chainstate/stacks/db/blocks.rs | 2 +- stackslib/src/chainstate/stacks/db/mod.rs | 6 +----- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/stackslib/src/chainstate/nakamoto/mod.rs b/stackslib/src/chainstate/nakamoto/mod.rs index 36e7cd8a3d..b4109ea81b 100644 --- a/stackslib/src/chainstate/nakamoto/mod.rs +++ b/stackslib/src/chainstate/nakamoto/mod.rs @@ -4693,7 +4693,7 @@ impl NakamotoChainState { .expect("FATAL: failed to advance chain tip"); let new_block_id = new_tip.index_block_hash(); - chainstate_tx.log_transactions_processed(&new_block_id, &tx_receipts); + chainstate_tx.log_transactions_processed(&tx_receipts); let reward_cycle = pox_constants .block_height_to_reward_cycle(first_block_height, chain_tip_burn_header_height.into()); diff --git a/stackslib/src/chainstate/stacks/db/blocks.rs b/stackslib/src/chainstate/stacks/db/blocks.rs index 8e6c0da9de..126e19657f 100644 --- a/stackslib/src/chainstate/stacks/db/blocks.rs +++ b/stackslib/src/chainstate/stacks/db/blocks.rs @@ -5847,7 +5847,7 @@ impl StacksChainState { ) .expect("FATAL: failed to advance chain tip"); - chainstate_tx.log_transactions_processed(&new_tip.index_block_hash(), &tx_receipts); + chainstate_tx.log_transactions_processed(&tx_receipts); // store the reward set calculated during this block if it happened // NOTE: miner and proposal evaluation should not invoke this because diff --git a/stackslib/src/chainstate/stacks/db/mod.rs b/stackslib/src/chainstate/stacks/db/mod.rs index 0ea02d239d..63bfae79ad 100644 --- a/stackslib/src/chainstate/stacks/db/mod.rs +++ b/stackslib/src/chainstate/stacks/db/mod.rs @@ -631,11 +631,7 @@ impl<'a> ChainstateTx<'a> { &self.config } - pub fn log_transactions_processed( - &self, - block_id: &StacksBlockId, - events: &[StacksTransactionReceipt], - ) { + pub fn log_transactions_processed(&self, events: &[StacksTransactionReceipt]) { for tx_event in events.iter() { let txid = tx_event.transaction.txid(); if let Err(e) = monitoring::log_transaction_processed(&txid, &self.root_path) { From 69fe3ed2eb66110002bfd1c7d7fccaafd4437527 Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Fri, 14 Feb 2025 15:53:15 +0100 Subject: [PATCH 5/6] fixed transactions_indexing test --- stackslib/src/chainstate/nakamoto/coordinator/tests.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stackslib/src/chainstate/nakamoto/coordinator/tests.rs b/stackslib/src/chainstate/nakamoto/coordinator/tests.rs index bd0bcf1b33..869c009275 100644 --- a/stackslib/src/chainstate/nakamoto/coordinator/tests.rs +++ b/stackslib/src/chainstate/nakamoto/coordinator/tests.rs @@ -1587,7 +1587,8 @@ fn transactions_indexing() { StacksAddress::new( C32_ADDRESS_VERSION_TESTNET_SINGLESIG, Hash160::from_data(&index.to_be_bytes()), - ), + ) + .unwrap(), Some(AddressHashMode::SerializeP2PKH), )), max_amount: None, From 6a7ae7802a5930b58cf1cdce2e0df5286ecfe369 Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Fri, 14 Feb 2025 15:55:53 +0100 Subject: [PATCH 6/6] updated CHANGELOG --- stacks-signer/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/stacks-signer/CHANGELOG.md b/stacks-signer/CHANGELOG.md index 94f60f52fb..436f523b43 100644 --- a/stacks-signer/CHANGELOG.md +++ b/stacks-signer/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE - Introduced the `reorg_attempts_activity_timeout_ms` configuration option for signers which is used to determine the length of time after the last block of a tenure is confirmed that an incoming miner's attempts to reorg it are considered valid miner activity. - Add signer configuration option `tenure_idle_timeout_buffer_secs` to specify the number of seconds of buffer the signer will add to its tenure extend time that it sends to miners. The idea is to allow for some clock skew between the miner and signers, preventing the case where the miner attempts to tenure extend too early. +- Add `txindex` configuration option enabling the storage (and querying via api) of transactions. Note: the old STACKS_TRANSACTION_LOG environment var configuration is no more available. ### Changed