Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to the versioning scheme outlined in the [README.md](README.md).

## [3.3.0.0.1]

- Add indexes to `nakamoto_block_headers` to fix a performance regression. Node may take a few minutes to restart during the upgrade while the new indexes are created.

## [3.3.0.0.0]

### Added
Expand Down
8 changes: 8 additions & 0 deletions stackslib/src/chainstate/nakamoto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,14 @@ pub static NAKAMOTO_CHAINSTATE_SCHEMA_6: &[&str] = &[
"CREATE INDEX IF NOT EXISTS nakamoto_block_headers_by_ch_bv ON nakamoto_block_headers(consensus_hash, burn_view);"
];

pub static NAKAMOTO_CHAINSTATE_SCHEMA_7: &[&str] = &[
// schema change is JUST a new index, but the index is on a table
// created by a migration, so don't add the index to the CHAINSTATE_INDEXES
r#"UPDATE db_config SET version = "12";"#,
"CREATE INDEX IF NOT EXISTS naka_block_headers_by_burn_hash ON nakamoto_block_headers(burn_header_hash);",
"CREATE INDEX IF NOT EXISTS naka_block_headers_by_burn_ht ON nakamoto_block_headers(burn_header_height);"
];

#[cfg(test)]
mod fault_injection {
static PROCESS_BLOCK_STALL: std::sync::Mutex<bool> = std::sync::Mutex::new(false);
Expand Down
17 changes: 13 additions & 4 deletions stackslib/src/chainstate/stacks/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ use crate::chainstate::nakamoto::{
HeaderTypeNames, NakamotoBlockHeader, NakamotoChainState, NakamotoStagingBlocksConn,
NAKAMOTO_CHAINSTATE_SCHEMA_1, NAKAMOTO_CHAINSTATE_SCHEMA_2, NAKAMOTO_CHAINSTATE_SCHEMA_3,
NAKAMOTO_CHAINSTATE_SCHEMA_4, NAKAMOTO_CHAINSTATE_SCHEMA_5, NAKAMOTO_CHAINSTATE_SCHEMA_6,
NAKAMOTO_CHAINSTATE_SCHEMA_7,
};
use crate::chainstate::stacks::address::StacksAddressExtensions;
use crate::chainstate::stacks::boot::*;
Expand Down Expand Up @@ -282,8 +283,8 @@ impl DBConfig {
});
match epoch_id {
StacksEpochId::Epoch10 => true,
StacksEpochId::Epoch20 => (1..=11).contains(&version_u32),
StacksEpochId::Epoch2_05 => (2..=11).contains(&version_u32),
StacksEpochId::Epoch20 => (1..=12).contains(&version_u32),
StacksEpochId::Epoch2_05 => (2..=12).contains(&version_u32),
StacksEpochId::Epoch21
| StacksEpochId::Epoch22
| StacksEpochId::Epoch23
Expand All @@ -292,7 +293,7 @@ impl DBConfig {
| StacksEpochId::Epoch30
| StacksEpochId::Epoch31
| StacksEpochId::Epoch32
| StacksEpochId::Epoch33 => (3..=11).contains(&version_u32),
| StacksEpochId::Epoch33 => (3..=12).contains(&version_u32),
}
}
}
Expand Down Expand Up @@ -651,7 +652,7 @@ impl<'a> DerefMut for ChainstateTx<'a> {
}
}

pub const CHAINSTATE_VERSION: &str = "11";
pub const CHAINSTATE_VERSION: &str = "12";

const CHAINSTATE_INITIAL_SCHEMA: &[&str] = &[
"PRAGMA foreign_keys = ON;",
Expand Down Expand Up @@ -1144,6 +1145,14 @@ impl StacksChainState {
tx.execute_batch(cmd)?;
}
}
"11" => {
info!(
"Migrating chainstate schema from version 11 to 12: add index for nakamoto_block_headers"
);
for cmd in NAKAMOTO_CHAINSTATE_SCHEMA_7.iter() {
tx.execute_batch(cmd)?;
}
}
_ => {
error!(
"Invalid chain state database: expected version = {}, got {}",
Expand Down
19 changes: 11 additions & 8 deletions stackslib/src/chainstate/stacks/db/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1560,13 +1560,14 @@ impl StacksChainState {

// what version of Clarity did the transaction caller want? And, is it valid now?
let clarity_version = StacksChainState::get_tx_clarity_version(clarity_block, tx)?;
if clarity_version == ClarityVersion::Clarity2 {
// requires 2.1 and higher
if clarity_block.get_epoch() < StacksEpochId::Epoch21 {
let msg = format!("Invalid transaction {}: asks for Clarity2, but not in Stacks epoch 2.1 or later", tx.txid());
info!("{}", &msg);
return Err(Error::InvalidStacksTransaction(msg, false));
}
if clarity_version > ClarityVersion::default_for_epoch(epoch) {
let msg = format!(
"Invalid transaction {}: asks for {clarity_version}, but current epoch {epoch} only supports up to {}",
tx.txid(),
ClarityVersion::default_for_epoch(epoch)
);
info!("{msg}");
return Err(Error::InvalidStacksTransaction(msg, false));
}

let mut transaction = clarity_block.connection().start_transaction_processing();
Expand Down Expand Up @@ -8668,7 +8669,9 @@ pub mod test {
if let Err(Error::InvalidStacksTransaction(msg, ..)) =
StacksChainState::process_transaction(&mut conn, &smart_contract_v2, false, None)
{
assert!(msg.find("not in Stacks epoch 2.1 or later").is_some());
assert!(msg
.find("asks for Clarity 2, but current epoch 2.05 only supports up to Clarity 1")
.is_some());
} else {
panic!("FATAL: did not recieve the appropriate error in processing a clarity2 tx in pre-2.1 epoch");
}
Expand Down
4 changes: 2 additions & 2 deletions versions.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Update these values when a new release is created.
# `stacks-common/build.rs` will automatically update `versions.rs` with these values.
stacks_node_version = "3.3.0.0.0"
stacks_signer_version = "3.3.0.0.0.0"
stacks_node_version = "3.3.0.0.1"
stacks_signer_version = "3.3.0.0.1.0"
Loading