Skip to content

Commit 813dc9b

Browse files
authored
Merge branch 'develop' into chore/stacks-node-logs
2 parents 3c812cf + d11ed3c commit 813dc9b

File tree

7 files changed

+42
-38
lines changed

7 files changed

+42
-38
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
77

88
## [Unreleased]
99

10+
### Changed
11+
- Add index for StacksBlockId to nakamoto block headers table (improves node performance)
12+
- Remove the panic for reporting DB deadlocks (just error and continue waiting)
13+
1014
## [3.0.0.0.0]
1115

1216
### Added

stacks-common/src/util/db.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,26 +51,25 @@ pub fn update_lock_table(conn: &Connection) {
5151
/// Called by `rusqlite` if we are waiting too long on a database lock
5252
/// If called too many times, will assume a deadlock and panic
5353
pub fn tx_busy_handler(run_count: i32) -> bool {
54-
const TIMEOUT: Duration = Duration::from_secs(300);
5554
const AVG_SLEEP_TIME_MS: u64 = 100;
5655

56+
// Every ~5min, report an error with a backtrace
57+
// 5min * 60s/min * 1_000ms/s / 100ms
58+
const ERROR_COUNT: u32 = 3_000;
59+
5760
// First, check if this is taking unreasonably long. If so, it's probably a deadlock
5861
let run_count = run_count.unsigned_abs();
59-
let approx_time_elapsed =
60-
Duration::from_millis(AVG_SLEEP_TIME_MS.saturating_mul(u64::from(run_count)));
61-
if approx_time_elapsed > TIMEOUT {
62-
error!("Deadlock detected. Waited {} seconds (estimated) for database lock. Giving up", approx_time_elapsed.as_secs();
62+
if run_count > 0 && run_count % ERROR_COUNT == 0 {
63+
error!("Deadlock detected. Waited 5 minutes (estimated) for database lock.";
6364
"run_count" => run_count,
6465
"backtrace" => ?Backtrace::capture()
6566
);
6667
for (k, v) in LOCK_TABLE.lock().unwrap().iter() {
6768
error!("Database '{k}' last locked by {v}");
6869
}
69-
panic!("Deadlock in thread {:?}", thread::current().name());
7070
}
7171

7272
let mut sleep_time_ms = 2u64.saturating_pow(run_count);
73-
7473
sleep_time_ms = sleep_time_ms.saturating_add(thread_rng().gen_range(0..sleep_time_ms));
7574

7675
if sleep_time_ms > AVG_SLEEP_TIME_MS {

stackslib/src/chainstate/nakamoto/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,14 @@ lazy_static! {
289289
);
290290
"#,
291291
];
292+
293+
pub static ref NAKAMOTO_CHAINSTATE_SCHEMA_5: [&'static str; 2] = [
294+
r#"
295+
UPDATE db_config SET version = "8";
296+
"#,
297+
// Add an index for index block hash in nakamoto block headers
298+
"CREATE INDEX IF NOT EXISTS index_block_hash ON nakamoto_block_headers(index_block_hash);",
299+
];
292300
}
293301

294302
#[cfg(test)]

stackslib/src/chainstate/stacks/db/mod.rs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ use crate::chainstate::burn::{ConsensusHash, ConsensusHashExtensions};
5555
use crate::chainstate::nakamoto::{
5656
HeaderTypeNames, NakamotoBlock, NakamotoBlockHeader, NakamotoChainState,
5757
NakamotoStagingBlocksConn, NAKAMOTO_CHAINSTATE_SCHEMA_1, NAKAMOTO_CHAINSTATE_SCHEMA_2,
58-
NAKAMOTO_CHAINSTATE_SCHEMA_3, NAKAMOTO_CHAINSTATE_SCHEMA_4,
58+
NAKAMOTO_CHAINSTATE_SCHEMA_3, NAKAMOTO_CHAINSTATE_SCHEMA_4, NAKAMOTO_CHAINSTATE_SCHEMA_5,
5959
};
6060
use crate::chainstate::stacks::address::StacksAddressExtensions;
6161
use crate::chainstate::stacks::boot::*;
@@ -299,14 +299,14 @@ impl DBConfig {
299299
});
300300
match epoch_id {
301301
StacksEpochId::Epoch10 => true,
302-
StacksEpochId::Epoch20 => version_u32 >= 1 && version_u32 <= 7,
303-
StacksEpochId::Epoch2_05 => version_u32 >= 2 && version_u32 <= 7,
304-
StacksEpochId::Epoch21 => version_u32 >= 3 && version_u32 <= 7,
305-
StacksEpochId::Epoch22 => version_u32 >= 3 && version_u32 <= 7,
306-
StacksEpochId::Epoch23 => version_u32 >= 3 && version_u32 <= 7,
307-
StacksEpochId::Epoch24 => version_u32 >= 3 && version_u32 <= 7,
308-
StacksEpochId::Epoch25 => version_u32 >= 3 && version_u32 <= 7,
309-
StacksEpochId::Epoch30 => version_u32 >= 3 && version_u32 <= 7,
302+
StacksEpochId::Epoch20 => version_u32 >= 1 && version_u32 <= 8,
303+
StacksEpochId::Epoch2_05 => version_u32 >= 2 && version_u32 <= 8,
304+
StacksEpochId::Epoch21 => version_u32 >= 3 && version_u32 <= 8,
305+
StacksEpochId::Epoch22 => version_u32 >= 3 && version_u32 <= 8,
306+
StacksEpochId::Epoch23 => version_u32 >= 3 && version_u32 <= 8,
307+
StacksEpochId::Epoch24 => version_u32 >= 3 && version_u32 <= 8,
308+
StacksEpochId::Epoch25 => version_u32 >= 3 && version_u32 <= 8,
309+
StacksEpochId::Epoch30 => version_u32 >= 3 && version_u32 <= 8,
310310
}
311311
}
312312
}
@@ -680,7 +680,7 @@ impl<'a> DerefMut for ChainstateTx<'a> {
680680
}
681681
}
682682

683-
pub const CHAINSTATE_VERSION: &'static str = "7";
683+
pub const CHAINSTATE_VERSION: &'static str = "8";
684684

685685
const CHAINSTATE_INITIAL_SCHEMA: &'static [&'static str] = &[
686686
"PRAGMA foreign_keys = ON;",
@@ -1087,28 +1087,24 @@ impl StacksChainState {
10871087
while db_config.version != CHAINSTATE_VERSION {
10881088
match db_config.version.as_str() {
10891089
"1" => {
1090-
// migrate to 2
10911090
info!("Migrating chainstate schema from version 1 to 2");
10921091
for cmd in CHAINSTATE_SCHEMA_2.iter() {
10931092
tx.execute_batch(cmd)?;
10941093
}
10951094
}
10961095
"2" => {
1097-
// migrate to 3
10981096
info!("Migrating chainstate schema from version 2 to 3");
10991097
for cmd in CHAINSTATE_SCHEMA_3.iter() {
11001098
tx.execute_batch(cmd)?;
11011099
}
11021100
}
11031101
"3" => {
1104-
// migrate to nakamoto 1
11051102
info!("Migrating chainstate schema from version 3 to 4: nakamoto support");
11061103
for cmd in NAKAMOTO_CHAINSTATE_SCHEMA_1.iter() {
11071104
tx.execute_batch(cmd)?;
11081105
}
11091106
}
11101107
"4" => {
1111-
// migrate to nakamoto 2
11121108
info!(
11131109
"Migrating chainstate schema from version 4 to 5: fix nakamoto tenure typo"
11141110
);
@@ -1117,21 +1113,27 @@ impl StacksChainState {
11171113
}
11181114
}
11191115
"5" => {
1120-
// migrate to nakamoto 3
11211116
info!("Migrating chainstate schema from version 5 to 6: adds height_in_tenure field");
11221117
for cmd in NAKAMOTO_CHAINSTATE_SCHEMA_3.iter() {
11231118
tx.execute_batch(cmd)?;
11241119
}
11251120
}
11261121
"6" => {
1127-
// migrate to nakamoto 3
11281122
info!(
11291123
"Migrating chainstate schema from version 6 to 7: adds signer_stats table"
11301124
);
11311125
for cmd in NAKAMOTO_CHAINSTATE_SCHEMA_4.iter() {
11321126
tx.execute_batch(cmd)?;
11331127
}
11341128
}
1129+
"7" => {
1130+
info!(
1131+
"Migrating chainstate schema from version 7 to 8: add index for nakamoto block headers"
1132+
);
1133+
for cmd in NAKAMOTO_CHAINSTATE_SCHEMA_5.iter() {
1134+
tx.execute_batch(cmd)?;
1135+
}
1136+
}
11351137
_ => {
11361138
error!(
11371139
"Invalid chain state database: expected version = {}, got {}",

stackslib/src/net/api/getattachmentsinv.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,10 @@ impl HttpRequest for RPCGetAttachmentsInvRequestHandler {
9696
if key == "index_block_hash" {
9797
index_block_hash = StacksBlockId::from_hex(&value).ok();
9898
} else if key == "pages_indexes" {
99-
if let Ok(pages_indexes_value) = value.parse::<String>() {
100-
for entry in pages_indexes_value.split(',') {
101-
if let Ok(page_index) = entry.parse::<u32>() {
102-
page_indexes.insert(page_index);
103-
}
99+
let pages_indexes_value = value.to_string();
100+
for entry in pages_indexes_value.split(',') {
101+
if let Ok(page_index) = entry.parse::<u32>() {
102+
page_indexes.insert(page_index);
104103
}
105104
}
106105
}

testnet/stacks-node/src/nakamoto_node/relayer.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -303,13 +303,9 @@ impl RelayerThread {
303303

304304
/// have we waited for the right conditions under which to start mining a block off of our
305305
/// chain tip?
306-
#[allow(clippy::nonminimal_bool)]
307-
#[allow(clippy::eq_op)]
308306
fn has_waited_for_latest_blocks(&self) -> bool {
309307
// a network download pass took place
310-
(self.min_network_download_passes <= self.last_network_download_passes
311-
// a network inv pass took place
312-
&& self.min_network_download_passes <= self.last_network_download_passes)
308+
self.min_network_download_passes <= self.last_network_download_passes
313309
// we waited long enough for a download pass, but timed out waiting
314310
|| self.last_network_block_height_ts + (self.config.node.wait_time_for_blocks as u128) < get_epoch_time_ms()
315311
// we're not supposed to wait at all

testnet/stacks-node/src/neon_node.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2896,13 +2896,9 @@ impl RelayerThread {
28962896

28972897
/// have we waited for the right conditions under which to start mining a block off of our
28982898
/// chain tip?
2899-
#[allow(clippy::nonminimal_bool)]
2900-
#[allow(clippy::eq_op)]
29012899
pub fn has_waited_for_latest_blocks(&self) -> bool {
29022900
// a network download pass took place
2903-
(self.min_network_download_passes <= self.last_network_download_passes
2904-
// a network inv pass took place
2905-
&& self.min_network_download_passes <= self.last_network_download_passes)
2901+
self.min_network_download_passes <= self.last_network_download_passes
29062902
// we waited long enough for a download pass, but timed out waiting
29072903
|| self.last_network_block_height_ts + (self.config.node.wait_time_for_blocks as u128) < get_epoch_time_ms()
29082904
// we're not supposed to wait at all

0 commit comments

Comments
 (0)