Skip to content

Commit

Permalink
fix: only start database after grpc (#6730)
Browse files Browse the repository at this point in the history
The loading of the SMT takes so long now and GRPC only starts after this
has happened, so applications like Tari Universe can't use the GRPC to
check if the app is healthy.

NOTE: I am unable to test this as the base node no longer starts on
windows due to `(exit code: 0xc0000135, STATUS_DLL_NOT_FOUND)`
  • Loading branch information
stringhandler authored Dec 31, 2024
1 parent 766eaf3 commit 8c87bf7
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 28 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,11 @@ First you'll need to make sure you have a full development environment set up:
- [Build Tools for Visual Studio 2019](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools&rel=16)
- Perl for OpenSSL:
- OpenSSL:
- OpenSSL is compiled and statically linked by the included [rust-openssl](https://github.com/sfackler/rust-openssl) crate
- Perl is required to compile this source on Windows, please download and install [StrawberryPerl](https://strawberryperl.com/)
- install `vcpkg`
- install static openssl `vcpkg install openssl:x64-windows-static`
- set env var: `OPENSSL_DIR=C:\vcpkg\packages\openssl_x64-windows-static`, replace `C:\vcpkg` with the root where you installed vcpkg
- [Protocol Buffers](https://protobuf.dev/)
- Install from https://github.com/protocolbuffers/protobuf#protobuf-compiler-installation or if you using [The Package Manager for Windows](https://chocolatey.org/), run ```choco upgrade protoc -y```
Expand Down
4 changes: 4 additions & 0 deletions applications/minotari_node/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ pub struct BaseNodeContext {
}

impl BaseNodeContext {
pub fn start(&self) -> Result<(), ChainStorageError> {
self.blockchain_db.start()
}

/// Waits for shutdown of the base node state machine and comms.
/// This call consumes the NodeContainer instance.
pub async fn wait_for_shutdown(self) {
Expand Down
3 changes: 3 additions & 0 deletions applications/minotari_node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ pub async fn run_base_node_with_cli(
task::spawn(run_grpc(grpc, grpc_address, auth, tls_identity, shutdown.to_signal()));
}

ctx.start()
.map_err(|e| ExitError::new(ExitCode::UnknownError, &format!("Could not start database.{:?}", e)))?;

// Run, node, run!
let context = CommandContext::new(&ctx, shutdown.clone());
let main_loop = CliLoop::new(context, cli.watch, cli.non_interactive_mode);
Expand Down
2 changes: 2 additions & 0 deletions applications/minotari_node/src/recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ pub async fn run_recovery(node_config: &BaseNodeConfig) -> Result<(), anyhow::Er
difficulty_calculator,
smt,
)?;
db.start()?;
do_recovery(db.into(), temp_db).await?;

info!(
Expand Down Expand Up @@ -154,6 +155,7 @@ async fn do_recovery<D: BlockchainBackend + 'static>(
DifficultyCalculator::new(rules, Default::default()),
smt,
)?;
source_database.start()?;
let max_height = source_database
.get_chain_metadata()
.map_err(|e| anyhow!("Could not get max chain height: {}", e))?
Expand Down
1 change: 0 additions & 1 deletion base_layer/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ criterion = { version = "0.4.0" }
tari_p2p = { path = "../../base_layer/p2p", features = ["test-mocks"] }
tari_test_utils = { path = "../../infrastructure/test_utils" }
# SQLite required for the integration tests
libsqlite3-sys = { version = "0.25.1", features = ["bundled"] }
config = { version = "0.14.0" }
env_logger = "0.7.0"
tempfile = "3.1.0"
Expand Down
58 changes: 43 additions & 15 deletions base_layer/core/src/chain_storage/blockchain_database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,6 @@ where B: BlockchainBackend
smt: Arc<RwLock<OutputSmt>>,
) -> Result<Self, ChainStorageError> {
debug!(target: LOG_TARGET, "BlockchainDatabase config: {:?}", config);
let is_empty = db.is_empty()?;
let blockchain_db = BlockchainDatabase {
db: Arc::new(RwLock::new(db)),
validators,
Expand All @@ -240,17 +239,46 @@ where B: BlockchainBackend
disable_add_block_flag: Arc::new(AtomicBool::new(false)),
smt,
};
let genesis_block = Arc::new(blockchain_db.consensus_manager.get_genesis_block());
Ok(blockchain_db)
}

pub fn start_new(
db: B,
consensus_manager: ConsensusManager,
validators: Validators<B>,
config: BlockchainDatabaseConfig,
difficulty_calculator: DifficultyCalculator,
smt: Arc<RwLock<OutputSmt>>,
) -> Result<Self, ChainStorageError> {
let blockchain_db = BlockchainDatabase {
db: Arc::new(RwLock::new(db)),
validators,
config,
consensus_manager,
difficulty_calculator: Arc::new(difficulty_calculator),
disable_add_block_flag: Arc::new(AtomicBool::new(false)),
smt,
};
blockchain_db.start()?;
Ok(blockchain_db)
}

pub fn start(&self) -> Result<(), ChainStorageError> {
let (is_empty, config) = {
let db = self.db_read_access()?;
(db.is_empty()?, &self.config)
};
let genesis_block = Arc::new(self.consensus_manager.get_genesis_block());
if is_empty {
info!(
target: LOG_TARGET,
"Blockchain db is empty. Adding genesis block {}.",
genesis_block.block().body.to_counts_string()
);
let mut txn = DbTransaction::new();
blockchain_db.write(txn)?;
self.write(txn)?;
txn = DbTransaction::new();
blockchain_db.insert_block(genesis_block.clone())?;
self.insert_block(genesis_block.clone())?;
let body = &genesis_block.block().body;
let input_sum = body
.inputs()
Expand All @@ -268,15 +296,15 @@ where B: BlockchainBackend
});
txn.set_pruned_height(0);
txn.set_horizon_data(kernel_sum, total_utxo_sum);
blockchain_db.write(txn)?;
blockchain_db.store_pruning_horizon(config.pruning_horizon)?;
} else if !blockchain_db.chain_block_or_orphan_block_exists(genesis_block.accumulated_data().hash)? {
self.write(txn)?;
self.store_pruning_horizon(config.pruning_horizon)?;
} else if !self.chain_block_or_orphan_block_exists(genesis_block.accumulated_data().hash)? {
// Check the genesis block in the DB.
error!(
target: LOG_TARGET,
"Genesis block in database does not match the supplied genesis block in the code! Hash in the code \
{:?}, hash in the database {:?}",
blockchain_db.fetch_chain_header(0)?.hash(),
self.fetch_chain_header(0)?.hash(),
genesis_block.accumulated_data().hash
);
return Err(ChainStorageError::CorruptedDatabase(
Expand All @@ -286,13 +314,13 @@ where B: BlockchainBackend
));
} else {
// lets load the smt into memory
let mut smt = blockchain_db.smt_write_access()?;
let mut smt = self.smt_write_access()?;
warn!(target: LOG_TARGET, "Loading SMT into memory from stored db");
*smt = blockchain_db.db_write_access()?.calculate_tip_smt()?;
*smt = self.db_write_access()?.calculate_tip_smt()?;
warn!(target: LOG_TARGET, "Finished loading SMT into memory from stored db");
}
if config.cleanup_orphans_at_startup {
match blockchain_db.cleanup_all_orphans() {
match self.cleanup_all_orphans() {
Ok(_) => info!(target: LOG_TARGET, "Orphan database cleaned out at startup.",),
Err(e) => warn!(
target: LOG_TARGET,
Expand All @@ -301,20 +329,20 @@ where B: BlockchainBackend
}
}

let pruning_horizon = blockchain_db.get_chain_metadata()?.pruning_horizon();
let pruning_horizon = self.get_chain_metadata()?.pruning_horizon();
if config.pruning_horizon != pruning_horizon {
debug!(
target: LOG_TARGET,
"Updating pruning horizon from {} to {}.", pruning_horizon, config.pruning_horizon,
);
blockchain_db.store_pruning_horizon(config.pruning_horizon)?;
self.store_pruning_horizon(config.pruning_horizon)?;
}

if !config.track_reorgs {
blockchain_db.clear_all_reorgs()?;
self.clear_all_reorgs()?;
}

Ok(blockchain_db)
Ok(())
}

/// Get the genesis block form the consensus manager
Expand Down
2 changes: 1 addition & 1 deletion base_layer/core/src/test_helpers/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ pub fn create_store_with_consensus_and_validators_and_config(
smt: Arc<RwLock<OutputSmt>>,
) -> BlockchainDatabase<TempDatabase> {
let backend = create_test_db();
BlockchainDatabase::new(
BlockchainDatabase::start_new(
backend,
rules.clone(),
validators,
Expand Down
2 changes: 1 addition & 1 deletion base_layer/core/tests/helpers/sample_blockchains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ pub async fn create_new_blockchain_lmdb(
.unwrap();
let db = TempDatabase::new();
let smt = Arc::new(RwLock::new(OutputSmt::new()));
let db = BlockchainDatabase::new(
let db = BlockchainDatabase::start_new(
db,
consensus_manager.clone(),
validators,
Expand Down
12 changes: 6 additions & 6 deletions base_layer/core/tests/tests/block_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ async fn test_orphan_validator() {
HeaderFullValidator::new(rules.clone(), difficulty_calculator.clone()),
orphan_validator.clone(),
);
let db = BlockchainDatabase::new(
let db = BlockchainDatabase::start_new(
backend,
rules.clone(),
validators,
Expand Down Expand Up @@ -510,7 +510,7 @@ async fn test_orphan_body_validation() {
HeaderFullValidator::new(rules.clone(), difficulty_calculator),
BlockBodyInternalConsistencyValidator::new(rules.clone(), false, factories.clone()),
);
let db = BlockchainDatabase::new(
let db = BlockchainDatabase::start_new(
backend,
rules.clone(),
validators,
Expand Down Expand Up @@ -731,7 +731,7 @@ async fn test_header_validation() {
HeaderFullValidator::new(rules.clone(), difficulty_calculator.clone()),
BlockBodyInternalConsistencyValidator::new(rules.clone(), false, factories.clone()),
);
let db = BlockchainDatabase::new(
let db = BlockchainDatabase::start_new(
backend,
rules.clone(),
validators,
Expand Down Expand Up @@ -847,7 +847,7 @@ async fn test_block_sync_body_validator() {
BlockBodyInternalConsistencyValidator::new(rules.clone(), false, factories.clone()),
);

let db = BlockchainDatabase::new(
let db = BlockchainDatabase::start_new(
backend,
rules.clone(),
validators,
Expand Down Expand Up @@ -1138,7 +1138,7 @@ async fn add_block_with_large_block() {
BlockBodyInternalConsistencyValidator::new(rules.clone(), false, factories.clone()),
);

let db = BlockchainDatabase::new(
let db = BlockchainDatabase::start_new(
backend,
rules.clone(),
validators,
Expand Down Expand Up @@ -1199,7 +1199,7 @@ async fn add_block_with_large_many_output_block() {
BlockBodyInternalConsistencyValidator::new(rules.clone(), false, factories.clone()),
);

let db = BlockchainDatabase::new(
let db = BlockchainDatabase::start_new(
backend,
rules.clone(),
validators,
Expand Down

0 comments on commit 8c87bf7

Please sign in to comment.