2020-06-15 15:41:10 -07:00
|
|
|
//! `start` subcommand - entry point for starting a zebra node
|
2020-06-15 16:16:46 -07:00
|
|
|
//!
|
2021-12-21 18:07:52 -08:00
|
|
|
//! ## Application Structure
|
2020-06-15 16:16:46 -07:00
|
|
|
//!
|
2023-06-06 01:28:14 -07:00
|
|
|
//! A zebra node consists of the following major services and tasks:
|
2020-06-15 16:16:46 -07:00
|
|
|
//!
|
2021-10-18 12:23:21 -07:00
|
|
|
//! Peers:
|
2022-01-20 05:43:23 -08:00
|
|
|
//! * Peer Connection Pool Service
|
|
|
|
//! * primary external interface for outbound requests from this node to remote peers
|
|
|
|
//! * accepts requests from services and tasks in this node, and sends them to remote peers
|
|
|
|
//! * Peer Discovery Service
|
|
|
|
//! * maintains a list of peer addresses, and connection priority metadata
|
|
|
|
//! * discovers new peer addresses from existing peer connections
|
|
|
|
//! * initiates new outbound peer connections in response to demand from tasks within this node
|
2023-06-06 01:28:14 -07:00
|
|
|
//! * Peer Cache Service
|
|
|
|
//! * Reads previous peer cache on startup, and adds it to the configured DNS seed peers
|
|
|
|
//! * Periodically updates the peer cache on disk from the latest address book state
|
2021-10-18 12:23:21 -07:00
|
|
|
//!
|
|
|
|
//! Blocks & Mempool Transactions:
|
2020-06-15 16:16:46 -07:00
|
|
|
//! * Consensus Service
|
|
|
|
//! * handles all validation logic for the node
|
2021-10-18 12:23:21 -07:00
|
|
|
//! * verifies blocks using zebra-chain, then stores verified blocks in zebra-state
|
|
|
|
//! * verifies mempool and block transactions using zebra-chain and zebra-script,
|
|
|
|
//! and returns verified mempool transactions for mempool storage
|
2021-11-25 08:26:32 -08:00
|
|
|
//! * Groth16 Parameters Download Task
|
|
|
|
//! * downloads the Sprout and Sapling Groth16 circuit parameter files
|
|
|
|
//! * finishes when the download is complete and the download file hashes have been checked
|
2021-10-18 12:23:21 -07:00
|
|
|
//! * Inbound Service
|
2022-01-20 05:43:23 -08:00
|
|
|
//! * primary external interface for inbound peer requests to this node
|
2021-10-18 12:23:21 -07:00
|
|
|
//! * handles requests from peers for network data, chain data, and mempool transactions
|
|
|
|
//! * spawns download and verify tasks for each gossiped block
|
|
|
|
//! * sends gossiped transactions to the mempool service
|
|
|
|
//!
|
|
|
|
//! Blocks:
|
2020-06-15 16:16:46 -07:00
|
|
|
//! * Sync Task
|
2021-01-29 04:19:06 -08:00
|
|
|
//! * runs in the background and continuously queries the network for
|
|
|
|
//! new blocks to be verified and added to the local state
|
2021-10-18 12:23:21 -07:00
|
|
|
//! * spawns download and verify tasks for each crawled block
|
|
|
|
//! * State Service
|
|
|
|
//! * contextually verifies blocks
|
|
|
|
//! * handles in-memory storage of multiple non-finalized chains
|
|
|
|
//! * handles permanent storage of the best finalized chain
|
2022-06-20 17:59:51 -07:00
|
|
|
//! * Old State Version Cleanup Task
|
|
|
|
//! * deletes outdated state versions
|
2021-10-18 12:23:21 -07:00
|
|
|
//! * Block Gossip Task
|
|
|
|
//! * runs in the background and continuously queries the state for
|
|
|
|
//! newly committed blocks to be gossiped to peers
|
2022-02-12 15:43:12 -08:00
|
|
|
//! * Progress Task
|
|
|
|
//! * logs progress towards the chain tip
|
2021-10-18 12:23:21 -07:00
|
|
|
//!
|
|
|
|
//! Mempool Transactions:
|
|
|
|
//! * Mempool Service
|
|
|
|
//! * activates when the syncer is near the chain tip
|
|
|
|
//! * spawns download and verify tasks for each crawled or gossiped transaction
|
|
|
|
//! * handles in-memory storage of unmined transactions
|
|
|
|
//! * Queue Checker Task
|
|
|
|
//! * runs in the background, polling the mempool to store newly verified transactions
|
|
|
|
//! * Transaction Gossip Task
|
|
|
|
//! * runs in the background and gossips newly added mempool transactions
|
|
|
|
//! to peers
|
2022-03-11 05:58:22 -08:00
|
|
|
//!
|
|
|
|
//! Remote Procedure Calls:
|
|
|
|
//! * JSON-RPC Service
|
|
|
|
//! * answers RPC client requests using the State Service and Mempool Service
|
|
|
|
//! * submits client transactions to the node's mempool
|
2022-06-16 12:56:40 -07:00
|
|
|
//!
|
2023-04-13 01:42:17 -07:00
|
|
|
//! Zebra also has diagnostic support:
|
2022-06-16 12:56:40 -07:00
|
|
|
//! * [metrics](https://github.com/ZcashFoundation/zebra/blob/main/book/src/user/metrics.md)
|
|
|
|
//! * [tracing](https://github.com/ZcashFoundation/zebra/blob/main/book/src/user/tracing.md)
|
2023-04-13 01:42:17 -07:00
|
|
|
//! * [progress-bar](https://docs.rs/howudoin/0.1.1/howudoin)
|
2022-06-16 12:56:40 -07:00
|
|
|
//!
|
|
|
|
//! Some of the diagnostic features are optional, and need to be enabled at compile-time.
|
2020-07-20 21:00:22 -07:00
|
|
|
|
2023-06-06 23:03:42 -07:00
|
|
|
use abscissa_core::{config, Command, FrameworkError, Runnable};
|
2020-09-18 12:18:22 -07:00
|
|
|
use color_eyre::eyre::{eyre, Report};
|
2021-11-19 15:02:56 -08:00
|
|
|
use futures::FutureExt;
|
|
|
|
use tokio::{pin, select, sync::oneshot};
|
2021-10-12 10:31:54 -07:00
|
|
|
use tower::{builder::ServiceBuilder, util::BoxService};
|
2022-01-28 14:12:19 -08:00
|
|
|
use tracing_futures::Instrument;
|
2020-09-18 12:18:22 -07:00
|
|
|
|
2023-06-01 05:29:03 -07:00
|
|
|
use zebra_consensus::router::BackgroundTaskHandles;
|
2022-02-22 03:26:29 -08:00
|
|
|
use zebra_rpc::server::RpcServer;
|
|
|
|
|
2020-09-09 12:03:09 -07:00
|
|
|
use crate::{
|
2023-06-19 19:42:06 -07:00
|
|
|
application::{build_version, user_agent},
|
2021-09-08 11:51:17 -07:00
|
|
|
components::{
|
2023-06-14 17:43:41 -07:00
|
|
|
inbound::{self, InboundSetupData, MAX_INBOUND_RESPONSE_TIME},
|
2021-09-08 11:51:17 -07:00
|
|
|
mempool::{self, Mempool},
|
change(state): Write non-finalized blocks to the state in a separate thread, to avoid network and RPC hangs (#5257)
* Add a new block commit task and channels, that don't do anything yet
* Add last_block_hash_sent to the state service, to avoid database accesses
* Update last_block_hash_sent regardless of commit errors
* Rename a field to StateService.max_queued_finalized_height
* Commit finalized blocks to the state in a separate task
* Check for panics in the block write task
* Wait for the block commit task in tests, and check for errors
* Always run a proptest that sleeps once
* Add extra debugging to state shutdowns
* Work around a RocksDB shutdown bug
* Close the finalized block channel when we're finished with it
* Only reset state queue once per error
* Update some TODOs
* Add a module doc comment
* Drop channels and check for closed channels in the block commit task
* Close state channels and tasks on drop
* Remove some duplicate fields across StateService and ReadStateService
* Try tweaking the shutdown steps
* Update and clarify some comments
* Clarify another comment
* Don't try to cancel RocksDB background work on drop
* Fix up some comments
* Remove some duplicate code
* Remove redundant workarounds for shutdown issues
* Remode a redundant channel close in the block commit task
* Remove a mistaken `!force` shutdown condition
* Remove duplicate force-shutdown code and explain it better
* Improve RPC error logging
* Wait for chain tip updates in the RPC tests
* Wait 2 seconds for chain tip updates before skipping them
* Remove an unnecessary block_in_place()
* Fix some test error messages that were changed by earlier fixes
* Expand some comments, fix typos
Co-authored-by: Marek <mail@marek.onl>
* Actually drop children of failed blocks
* Explain why we drop descendants of failed blocks
* Clarify a comment
* Wait for chain tip updates in a failing test on macOS
* Clean duplicate finalized blocks when the non-finalized state activates
* Send an error when receiving a duplicate finalized block
* Update checkpoint block behaviour, document its consensus rule
* Wait for chain tip changes in inbound_block_height_lookahead_limit test
* Wait for the genesis block to commit in the fake peer set mempool tests
* Disable unreliable mempool verification check in the send transaction test
* Appease rustfmt
* Use clear_finalized_block_queue() everywhere that blocks are dropped
* Document how Finalized and NonFinalized clones are different
* sends non-finalized blocks to the block write task
* passes ZebraDb to commit_new_chain, commit_block, and no_duplicates_in_finalized_chain instead of FinalizedState
* Update zebra-state/src/service/write.rs
Co-authored-by: teor <teor@riseup.net>
* updates comments, renames send_process_queued, other minor cleanup
* update assert_block_can_be_validated comment
* removes `mem` field from StateService
* removes `disk` field from StateService and updates block_iter to use `ZebraDb` instead of the finalized state
* updates tests that use the disk to use read_service.db instead
* moves best_tip to a read fn and returns finalized & non-finalized states from setup instead of the state service
* changes `contextual_validity` to get the network from the finalized_state instead of another param
* swaps out StateService with FinalizedState and NonFinalizedState in tests
* adds NotReadyToBeCommitted error and returns it from validate_and_commit when a blocks parent hash is not in any chain
* removes NonFinalizedWriteCmd and calls, moves update_latest_channels above rsp_tx.send
* makes parent_errors_map an indexmap
* clears non-finalized block queue when the receiver is dropped and when the StateService is being dropped
* sends non-finalized blocks to the block write task
* passes ZebraDb to commit_new_chain, commit_block, and no_duplicates_in_finalized_chain instead of FinalizedState
* updates comments, renames send_process_queued, other minor cleanup
* Update zebra-state/src/service/write.rs
Co-authored-by: teor <teor@riseup.net>
* update assert_block_can_be_validated comment
* removes `mem` field from StateService
* removes `disk` field from StateService and updates block_iter to use `ZebraDb` instead of the finalized state
* updates tests that use the disk to use read_service.db instead
* moves best_tip to a read fn and returns finalized & non-finalized states from setup instead of the state service
* changes `contextual_validity` to get the network from the finalized_state instead of another param
* swaps out StateService with FinalizedState and NonFinalizedState in tests
* adds NotReadyToBeCommitted error and returns it from validate_and_commit when a blocks parent hash is not in any chain
* removes NonFinalizedWriteCmd and calls, moves update_latest_channels above rsp_tx.send
* makes parent_errors_map an indexmap
* clears non-finalized block queue when the receiver is dropped and when the StateService is being dropped
* removes duplicate field definitions on StateService that were a result of a bad merge
* update NotReadyToBeCommitted error message
* Appear rustfmt
* Fix doc links
* Rename a function to initial_contextual_validity()
* Do error tasks on Err, and success tasks on Ok
* Simplify parent_error_map truncation
* Rewrite best_tip() to use tip()
* Rename latest_mem() to latest_non_finalized_state()
```sh
fastmod latest_mem latest_non_finalized_state zebra*
cargo fmt --all
```
* Simplify latest_non_finalized_state() using a new WatchReceiver API
* Expand some error messages
* Send the result after updating the channels, and document why
* wait for chain_tip_update before cancelling download in mempool_cancel_mined
* adds `sent_non_finalized_block_hashes` field to StateService
* adds batched sent_hash insertions and checks sent hashes in queue_and_commit_non_finalized before adding a block to the queue
* check that the `curr_buf` in SentHashes is not empty before pushing it to the `sent_bufs`
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* Fix rustfmt
* Check for finalized block heights using zs_contains()
* adds known_utxos field to SentHashes
* updates comment on SentHashes.add method
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* return early when there's a duplicate hash in QueuedBlocks.queue instead of panicking
* Make finalized UTXOs near the final checkpoint available for full block verification
* Replace a checkpoint height literal with the actual config
* Update mainnet and testnet checkpoints - 7 October 2022
* Fix some state service init arguments
* Allow more lookahead in the downloader, but less lookahead in the syncer
* Add the latest config to the tests, and fix the latest config check
* Increase the number of finalized blocks checked for non-finalized block UTXO spends
* fix(log): reduce verbose logs for block commits (#5348)
* Remove some verbose block write channel logs
* Only warn about tracing endpoint if the address is actually set
* Use CloneError instead of formatting a non-cloneable error
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
* Increase block verify timeout
* Work around a known block timeout bug by using a shorter timeout
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: Marek <mail@marek.onl>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-10-11 12:25:45 -07:00
|
|
|
sync::{self, show_block_chain_progress, VERIFICATION_PIPELINE_SCALING_MULTIPLIER},
|
2021-09-08 11:51:17 -07:00
|
|
|
tokio::{RuntimeRun, TokioComponent},
|
|
|
|
ChainSync, Inbound,
|
|
|
|
},
|
|
|
|
config::ZebradConfig,
|
2020-09-09 12:03:09 -07:00
|
|
|
prelude::*,
|
|
|
|
};
|
2020-07-20 21:00:22 -07:00
|
|
|
|
2023-06-06 23:03:42 -07:00
|
|
|
/// Start the application (default command)
|
|
|
|
#[derive(Command, Debug, Default, clap::Parser)]
|
2020-06-16 11:02:01 -07:00
|
|
|
pub struct StartCmd {
|
2021-12-09 16:19:52 -08:00
|
|
|
/// Filter strings which override the config file and defaults
|
2023-06-06 23:03:42 -07:00
|
|
|
#[clap(help = "tracing filters which override the zebrad.toml config")]
|
2019-09-09 13:05:42 -07:00
|
|
|
filters: Vec<String>,
|
2019-08-29 14:46:54 -07:00
|
|
|
}
|
|
|
|
|
2020-06-16 11:02:01 -07:00
|
|
|
impl StartCmd {
|
2020-06-15 17:07:55 -07:00
|
|
|
async fn start(&self) -> Result<(), Report> {
|
2023-06-06 23:03:42 -07:00
|
|
|
let config = APPLICATION.config();
|
2020-06-15 17:07:55 -07:00
|
|
|
|
2020-09-18 12:18:22 -07:00
|
|
|
info!("initializing node state");
|
2023-06-01 05:29:03 -07:00
|
|
|
let (_, max_checkpoint_height) = zebra_consensus::router::init_checkpoint_list(
|
change(state): Write non-finalized blocks to the state in a separate thread, to avoid network and RPC hangs (#5257)
* Add a new block commit task and channels, that don't do anything yet
* Add last_block_hash_sent to the state service, to avoid database accesses
* Update last_block_hash_sent regardless of commit errors
* Rename a field to StateService.max_queued_finalized_height
* Commit finalized blocks to the state in a separate task
* Check for panics in the block write task
* Wait for the block commit task in tests, and check for errors
* Always run a proptest that sleeps once
* Add extra debugging to state shutdowns
* Work around a RocksDB shutdown bug
* Close the finalized block channel when we're finished with it
* Only reset state queue once per error
* Update some TODOs
* Add a module doc comment
* Drop channels and check for closed channels in the block commit task
* Close state channels and tasks on drop
* Remove some duplicate fields across StateService and ReadStateService
* Try tweaking the shutdown steps
* Update and clarify some comments
* Clarify another comment
* Don't try to cancel RocksDB background work on drop
* Fix up some comments
* Remove some duplicate code
* Remove redundant workarounds for shutdown issues
* Remode a redundant channel close in the block commit task
* Remove a mistaken `!force` shutdown condition
* Remove duplicate force-shutdown code and explain it better
* Improve RPC error logging
* Wait for chain tip updates in the RPC tests
* Wait 2 seconds for chain tip updates before skipping them
* Remove an unnecessary block_in_place()
* Fix some test error messages that were changed by earlier fixes
* Expand some comments, fix typos
Co-authored-by: Marek <mail@marek.onl>
* Actually drop children of failed blocks
* Explain why we drop descendants of failed blocks
* Clarify a comment
* Wait for chain tip updates in a failing test on macOS
* Clean duplicate finalized blocks when the non-finalized state activates
* Send an error when receiving a duplicate finalized block
* Update checkpoint block behaviour, document its consensus rule
* Wait for chain tip changes in inbound_block_height_lookahead_limit test
* Wait for the genesis block to commit in the fake peer set mempool tests
* Disable unreliable mempool verification check in the send transaction test
* Appease rustfmt
* Use clear_finalized_block_queue() everywhere that blocks are dropped
* Document how Finalized and NonFinalized clones are different
* sends non-finalized blocks to the block write task
* passes ZebraDb to commit_new_chain, commit_block, and no_duplicates_in_finalized_chain instead of FinalizedState
* Update zebra-state/src/service/write.rs
Co-authored-by: teor <teor@riseup.net>
* updates comments, renames send_process_queued, other minor cleanup
* update assert_block_can_be_validated comment
* removes `mem` field from StateService
* removes `disk` field from StateService and updates block_iter to use `ZebraDb` instead of the finalized state
* updates tests that use the disk to use read_service.db instead
* moves best_tip to a read fn and returns finalized & non-finalized states from setup instead of the state service
* changes `contextual_validity` to get the network from the finalized_state instead of another param
* swaps out StateService with FinalizedState and NonFinalizedState in tests
* adds NotReadyToBeCommitted error and returns it from validate_and_commit when a blocks parent hash is not in any chain
* removes NonFinalizedWriteCmd and calls, moves update_latest_channels above rsp_tx.send
* makes parent_errors_map an indexmap
* clears non-finalized block queue when the receiver is dropped and when the StateService is being dropped
* sends non-finalized blocks to the block write task
* passes ZebraDb to commit_new_chain, commit_block, and no_duplicates_in_finalized_chain instead of FinalizedState
* updates comments, renames send_process_queued, other minor cleanup
* Update zebra-state/src/service/write.rs
Co-authored-by: teor <teor@riseup.net>
* update assert_block_can_be_validated comment
* removes `mem` field from StateService
* removes `disk` field from StateService and updates block_iter to use `ZebraDb` instead of the finalized state
* updates tests that use the disk to use read_service.db instead
* moves best_tip to a read fn and returns finalized & non-finalized states from setup instead of the state service
* changes `contextual_validity` to get the network from the finalized_state instead of another param
* swaps out StateService with FinalizedState and NonFinalizedState in tests
* adds NotReadyToBeCommitted error and returns it from validate_and_commit when a blocks parent hash is not in any chain
* removes NonFinalizedWriteCmd and calls, moves update_latest_channels above rsp_tx.send
* makes parent_errors_map an indexmap
* clears non-finalized block queue when the receiver is dropped and when the StateService is being dropped
* removes duplicate field definitions on StateService that were a result of a bad merge
* update NotReadyToBeCommitted error message
* Appear rustfmt
* Fix doc links
* Rename a function to initial_contextual_validity()
* Do error tasks on Err, and success tasks on Ok
* Simplify parent_error_map truncation
* Rewrite best_tip() to use tip()
* Rename latest_mem() to latest_non_finalized_state()
```sh
fastmod latest_mem latest_non_finalized_state zebra*
cargo fmt --all
```
* Simplify latest_non_finalized_state() using a new WatchReceiver API
* Expand some error messages
* Send the result after updating the channels, and document why
* wait for chain_tip_update before cancelling download in mempool_cancel_mined
* adds `sent_non_finalized_block_hashes` field to StateService
* adds batched sent_hash insertions and checks sent hashes in queue_and_commit_non_finalized before adding a block to the queue
* check that the `curr_buf` in SentHashes is not empty before pushing it to the `sent_bufs`
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* Fix rustfmt
* Check for finalized block heights using zs_contains()
* adds known_utxos field to SentHashes
* updates comment on SentHashes.add method
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* return early when there's a duplicate hash in QueuedBlocks.queue instead of panicking
* Make finalized UTXOs near the final checkpoint available for full block verification
* Replace a checkpoint height literal with the actual config
* Update mainnet and testnet checkpoints - 7 October 2022
* Fix some state service init arguments
* Allow more lookahead in the downloader, but less lookahead in the syncer
* Add the latest config to the tests, and fix the latest config check
* Increase the number of finalized blocks checked for non-finalized block UTXO spends
* fix(log): reduce verbose logs for block commits (#5348)
* Remove some verbose block write channel logs
* Only warn about tracing endpoint if the address is actually set
* Use CloneError instead of formatting a non-cloneable error
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
* Increase block verify timeout
* Work around a known block timeout bug by using a shorter timeout
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: Marek <mail@marek.onl>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-10-11 12:25:45 -07:00
|
|
|
config.consensus.clone(),
|
|
|
|
config.network.network,
|
|
|
|
);
|
|
|
|
|
|
|
|
info!("opening database, this may take a few minutes");
|
2022-09-26 08:45:42 -07:00
|
|
|
|
2022-03-15 12:50:28 -07:00
|
|
|
let (state_service, read_only_state_service, latest_chain_tip, chain_tip_change) =
|
change(state): Write non-finalized blocks to the state in a separate thread, to avoid network and RPC hangs (#5257)
* Add a new block commit task and channels, that don't do anything yet
* Add last_block_hash_sent to the state service, to avoid database accesses
* Update last_block_hash_sent regardless of commit errors
* Rename a field to StateService.max_queued_finalized_height
* Commit finalized blocks to the state in a separate task
* Check for panics in the block write task
* Wait for the block commit task in tests, and check for errors
* Always run a proptest that sleeps once
* Add extra debugging to state shutdowns
* Work around a RocksDB shutdown bug
* Close the finalized block channel when we're finished with it
* Only reset state queue once per error
* Update some TODOs
* Add a module doc comment
* Drop channels and check for closed channels in the block commit task
* Close state channels and tasks on drop
* Remove some duplicate fields across StateService and ReadStateService
* Try tweaking the shutdown steps
* Update and clarify some comments
* Clarify another comment
* Don't try to cancel RocksDB background work on drop
* Fix up some comments
* Remove some duplicate code
* Remove redundant workarounds for shutdown issues
* Remode a redundant channel close in the block commit task
* Remove a mistaken `!force` shutdown condition
* Remove duplicate force-shutdown code and explain it better
* Improve RPC error logging
* Wait for chain tip updates in the RPC tests
* Wait 2 seconds for chain tip updates before skipping them
* Remove an unnecessary block_in_place()
* Fix some test error messages that were changed by earlier fixes
* Expand some comments, fix typos
Co-authored-by: Marek <mail@marek.onl>
* Actually drop children of failed blocks
* Explain why we drop descendants of failed blocks
* Clarify a comment
* Wait for chain tip updates in a failing test on macOS
* Clean duplicate finalized blocks when the non-finalized state activates
* Send an error when receiving a duplicate finalized block
* Update checkpoint block behaviour, document its consensus rule
* Wait for chain tip changes in inbound_block_height_lookahead_limit test
* Wait for the genesis block to commit in the fake peer set mempool tests
* Disable unreliable mempool verification check in the send transaction test
* Appease rustfmt
* Use clear_finalized_block_queue() everywhere that blocks are dropped
* Document how Finalized and NonFinalized clones are different
* sends non-finalized blocks to the block write task
* passes ZebraDb to commit_new_chain, commit_block, and no_duplicates_in_finalized_chain instead of FinalizedState
* Update zebra-state/src/service/write.rs
Co-authored-by: teor <teor@riseup.net>
* updates comments, renames send_process_queued, other minor cleanup
* update assert_block_can_be_validated comment
* removes `mem` field from StateService
* removes `disk` field from StateService and updates block_iter to use `ZebraDb` instead of the finalized state
* updates tests that use the disk to use read_service.db instead
* moves best_tip to a read fn and returns finalized & non-finalized states from setup instead of the state service
* changes `contextual_validity` to get the network from the finalized_state instead of another param
* swaps out StateService with FinalizedState and NonFinalizedState in tests
* adds NotReadyToBeCommitted error and returns it from validate_and_commit when a blocks parent hash is not in any chain
* removes NonFinalizedWriteCmd and calls, moves update_latest_channels above rsp_tx.send
* makes parent_errors_map an indexmap
* clears non-finalized block queue when the receiver is dropped and when the StateService is being dropped
* sends non-finalized blocks to the block write task
* passes ZebraDb to commit_new_chain, commit_block, and no_duplicates_in_finalized_chain instead of FinalizedState
* updates comments, renames send_process_queued, other minor cleanup
* Update zebra-state/src/service/write.rs
Co-authored-by: teor <teor@riseup.net>
* update assert_block_can_be_validated comment
* removes `mem` field from StateService
* removes `disk` field from StateService and updates block_iter to use `ZebraDb` instead of the finalized state
* updates tests that use the disk to use read_service.db instead
* moves best_tip to a read fn and returns finalized & non-finalized states from setup instead of the state service
* changes `contextual_validity` to get the network from the finalized_state instead of another param
* swaps out StateService with FinalizedState and NonFinalizedState in tests
* adds NotReadyToBeCommitted error and returns it from validate_and_commit when a blocks parent hash is not in any chain
* removes NonFinalizedWriteCmd and calls, moves update_latest_channels above rsp_tx.send
* makes parent_errors_map an indexmap
* clears non-finalized block queue when the receiver is dropped and when the StateService is being dropped
* removes duplicate field definitions on StateService that were a result of a bad merge
* update NotReadyToBeCommitted error message
* Appear rustfmt
* Fix doc links
* Rename a function to initial_contextual_validity()
* Do error tasks on Err, and success tasks on Ok
* Simplify parent_error_map truncation
* Rewrite best_tip() to use tip()
* Rename latest_mem() to latest_non_finalized_state()
```sh
fastmod latest_mem latest_non_finalized_state zebra*
cargo fmt --all
```
* Simplify latest_non_finalized_state() using a new WatchReceiver API
* Expand some error messages
* Send the result after updating the channels, and document why
* wait for chain_tip_update before cancelling download in mempool_cancel_mined
* adds `sent_non_finalized_block_hashes` field to StateService
* adds batched sent_hash insertions and checks sent hashes in queue_and_commit_non_finalized before adding a block to the queue
* check that the `curr_buf` in SentHashes is not empty before pushing it to the `sent_bufs`
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* Fix rustfmt
* Check for finalized block heights using zs_contains()
* adds known_utxos field to SentHashes
* updates comment on SentHashes.add method
* Apply suggestions from code review
Co-authored-by: teor <teor@riseup.net>
* return early when there's a duplicate hash in QueuedBlocks.queue instead of panicking
* Make finalized UTXOs near the final checkpoint available for full block verification
* Replace a checkpoint height literal with the actual config
* Update mainnet and testnet checkpoints - 7 October 2022
* Fix some state service init arguments
* Allow more lookahead in the downloader, but less lookahead in the syncer
* Add the latest config to the tests, and fix the latest config check
* Increase the number of finalized blocks checked for non-finalized block UTXO spends
* fix(log): reduce verbose logs for block commits (#5348)
* Remove some verbose block write channel logs
* Only warn about tracing endpoint if the address is actually set
* Use CloneError instead of formatting a non-cloneable error
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
* Increase block verify timeout
* Work around a known block timeout bug by using a shorter timeout
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: Marek <mail@marek.onl>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-10-11 12:25:45 -07:00
|
|
|
zebra_state::spawn_init(
|
|
|
|
config.state.clone(),
|
|
|
|
config.network.network,
|
|
|
|
max_checkpoint_height,
|
|
|
|
config.sync.checkpoint_verify_concurrency_limit
|
|
|
|
* (VERIFICATION_PIPELINE_SCALING_MULTIPLIER + 1),
|
|
|
|
)
|
|
|
|
.await?;
|
2022-09-26 08:45:42 -07:00
|
|
|
|
2022-02-02 14:44:15 -08:00
|
|
|
let state = ServiceBuilder::new()
|
|
|
|
.buffer(Self::state_buffer_bound())
|
|
|
|
.service(state_service);
|
2020-09-18 12:18:22 -07:00
|
|
|
|
|
|
|
info!("initializing network");
|
2020-09-18 12:37:01 -07:00
|
|
|
// The service that our node uses to respond to requests by peers. The
|
|
|
|
// load_shed middleware ensures that we reduce the size of the peer set
|
|
|
|
// in response to excess load.
|
2023-06-14 17:43:41 -07:00
|
|
|
//
|
|
|
|
// # Security
|
|
|
|
//
|
|
|
|
// This layer stack is security-sensitive, modifying it can cause hangs,
|
|
|
|
// or enable denial of service attacks.
|
|
|
|
//
|
|
|
|
// See `zebra_network::Connection::drive_peer_request()` for details.
|
2020-09-18 12:18:22 -07:00
|
|
|
let (setup_tx, setup_rx) = oneshot::channel();
|
|
|
|
let inbound = ServiceBuilder::new()
|
|
|
|
.load_shed()
|
2022-02-02 14:44:15 -08:00
|
|
|
.buffer(inbound::downloads::MAX_INBOUND_CONCURRENCY)
|
2023-06-14 17:43:41 -07:00
|
|
|
.timeout(MAX_INBOUND_RESPONSE_TIME)
|
2022-07-06 07:13:57 -07:00
|
|
|
.service(Inbound::new(
|
|
|
|
config.sync.full_verify_concurrency_limit,
|
|
|
|
setup_rx,
|
|
|
|
));
|
2020-09-18 12:18:22 -07:00
|
|
|
|
2023-05-04 17:29:14 -07:00
|
|
|
let (peer_set, address_book) = zebra_network::init(
|
|
|
|
config.network.clone(),
|
|
|
|
inbound,
|
|
|
|
latest_chain_tip.clone(),
|
|
|
|
user_agent(),
|
|
|
|
)
|
|
|
|
.await;
|
2021-09-13 13:28:07 -07:00
|
|
|
|
2021-11-23 09:42:44 -08:00
|
|
|
info!("initializing verifiers");
|
2023-06-01 05:29:03 -07:00
|
|
|
let (router_verifier, tx_verifier, consensus_task_handles, max_checkpoint_height) =
|
|
|
|
zebra_consensus::router::init(
|
2021-11-23 09:42:44 -08:00
|
|
|
config.consensus.clone(),
|
|
|
|
config.network.network,
|
|
|
|
state.clone(),
|
2021-12-14 13:43:07 -08:00
|
|
|
config.consensus.debug_skip_parameter_preload,
|
2021-11-23 09:42:44 -08:00
|
|
|
)
|
|
|
|
.await;
|
|
|
|
|
2021-09-15 15:13:29 -07:00
|
|
|
info!("initializing syncer");
|
2021-11-23 09:42:44 -08:00
|
|
|
let (syncer, sync_status) = ChainSync::new(
|
|
|
|
&config,
|
2022-07-06 07:13:57 -07:00
|
|
|
max_checkpoint_height,
|
2021-11-23 09:42:44 -08:00
|
|
|
peer_set.clone(),
|
2023-06-01 05:29:03 -07:00
|
|
|
router_verifier.clone(),
|
2021-12-17 08:31:51 -08:00
|
|
|
state.clone(),
|
|
|
|
latest_chain_tip.clone(),
|
2021-11-23 09:42:44 -08:00
|
|
|
);
|
2021-09-15 15:13:29 -07:00
|
|
|
|
2021-09-13 13:28:07 -07:00
|
|
|
info!("initializing mempool");
|
2021-10-12 10:31:54 -07:00
|
|
|
let (mempool, mempool_transaction_receiver) = Mempool::new(
|
|
|
|
&config.mempool,
|
2021-09-13 13:28:07 -07:00
|
|
|
peer_set.clone(),
|
2021-11-23 09:42:44 -08:00
|
|
|
state.clone(),
|
2021-09-13 13:28:07 -07:00
|
|
|
tx_verifier,
|
2021-09-15 15:13:29 -07:00
|
|
|
sync_status.clone(),
|
2021-12-17 08:31:51 -08:00
|
|
|
latest_chain_tip.clone(),
|
2021-09-21 10:06:52 -07:00
|
|
|
chain_tip_change.clone(),
|
2021-10-12 10:31:54 -07:00
|
|
|
);
|
|
|
|
let mempool = BoxService::new(mempool);
|
2022-02-02 14:44:15 -08:00
|
|
|
let mempool = ServiceBuilder::new()
|
|
|
|
.buffer(mempool::downloads::MAX_INBOUND_CONCURRENCY)
|
|
|
|
.service(mempool);
|
2021-09-13 13:28:07 -07:00
|
|
|
|
2023-04-23 06:41:38 -07:00
|
|
|
info!("fully initializing inbound peer request handler");
|
|
|
|
// Fully start the inbound service as soon as possible
|
|
|
|
let setup_data = InboundSetupData {
|
|
|
|
address_book: address_book.clone(),
|
|
|
|
block_download_peer_set: peer_set.clone(),
|
2023-06-01 05:29:03 -07:00
|
|
|
block_verifier: router_verifier.clone(),
|
2023-04-23 06:41:38 -07:00
|
|
|
mempool: mempool.clone(),
|
|
|
|
state,
|
|
|
|
latest_chain_tip: latest_chain_tip.clone(),
|
|
|
|
};
|
|
|
|
setup_tx
|
|
|
|
.send(setup_data)
|
|
|
|
.map_err(|_| eyre!("could not send setup data to inbound service"))?;
|
|
|
|
// And give it time to clear its queue
|
|
|
|
tokio::task::yield_now().await;
|
|
|
|
|
2022-03-02 16:39:47 -08:00
|
|
|
// Launch RPC server
|
2022-11-10 06:51:53 -08:00
|
|
|
let (rpc_task_handle, rpc_tx_queue_task_handle, rpc_server) = RpcServer::spawn(
|
2023-06-06 23:03:42 -07:00
|
|
|
config.rpc.clone(),
|
2022-11-09 16:12:27 -08:00
|
|
|
#[cfg(feature = "getblocktemplate-rpcs")]
|
2023-06-06 23:03:42 -07:00
|
|
|
config.mining.clone(),
|
2022-11-09 16:12:27 -08:00
|
|
|
#[cfg(not(feature = "getblocktemplate-rpcs"))]
|
|
|
|
(),
|
2023-06-19 19:42:06 -07:00
|
|
|
build_version(),
|
|
|
|
user_agent(),
|
2022-03-09 17:12:41 -08:00
|
|
|
mempool.clone(),
|
2022-03-15 12:50:28 -07:00
|
|
|
read_only_state_service,
|
2023-06-01 05:29:03 -07:00
|
|
|
router_verifier,
|
2022-12-02 03:21:23 -08:00
|
|
|
sync_status.clone(),
|
2023-04-23 06:41:38 -07:00
|
|
|
address_book,
|
2022-03-15 15:29:15 -07:00
|
|
|
latest_chain_tip.clone(),
|
|
|
|
config.network.network,
|
2022-03-09 17:12:41 -08:00
|
|
|
);
|
2022-03-02 16:39:47 -08:00
|
|
|
|
2023-04-23 06:41:38 -07:00
|
|
|
// Start concurrent tasks which don't add load to other tasks
|
2022-04-11 22:06:29 -07:00
|
|
|
let block_gossip_task_handle = tokio::spawn(
|
2022-01-28 14:12:19 -08:00
|
|
|
sync::gossip_best_tip_block_hashes(
|
|
|
|
sync_status.clone(),
|
|
|
|
chain_tip_change.clone(),
|
|
|
|
peer_set.clone(),
|
|
|
|
)
|
|
|
|
.in_current_span(),
|
|
|
|
);
|
2021-10-07 03:46:37 -07:00
|
|
|
|
2022-03-08 01:14:21 -08:00
|
|
|
let mempool_queue_checker_task_handle = mempool::QueueChecker::spawn(mempool.clone());
|
2021-10-18 12:23:21 -07:00
|
|
|
|
2022-01-28 14:12:19 -08:00
|
|
|
let tx_gossip_task_handle = tokio::spawn(
|
2023-04-23 06:41:38 -07:00
|
|
|
mempool::gossip_mempool_transaction_id(mempool_transaction_receiver, peer_set.clone())
|
2022-01-28 14:12:19 -08:00
|
|
|
.in_current_span(),
|
|
|
|
);
|
2021-10-07 03:46:37 -07:00
|
|
|
|
2023-04-23 06:41:38 -07:00
|
|
|
let mut old_databases_task_handle =
|
|
|
|
zebra_state::check_and_delete_old_databases(config.state.clone());
|
|
|
|
|
2022-02-12 15:43:12 -08:00
|
|
|
let progress_task_handle = tokio::spawn(
|
2023-04-23 06:41:38 -07:00
|
|
|
show_block_chain_progress(
|
|
|
|
config.network.network,
|
2023-04-28 07:13:21 -07:00
|
|
|
latest_chain_tip.clone(),
|
2023-04-23 06:41:38 -07:00
|
|
|
sync_status.clone(),
|
|
|
|
)
|
|
|
|
.in_current_span(),
|
2022-02-12 15:43:12 -08:00
|
|
|
);
|
|
|
|
|
2023-04-28 07:13:21 -07:00
|
|
|
let end_of_support_task_handle = tokio::spawn(
|
|
|
|
sync::end_of_support::start(config.network.network, latest_chain_tip).in_current_span(),
|
|
|
|
);
|
|
|
|
|
2023-04-23 06:41:38 -07:00
|
|
|
// Give the inbound service more time to clear its queue,
|
|
|
|
// then start concurrent tasks that can add load to the inbound service
|
|
|
|
// (by opening more peer connections, so those peers send us requests)
|
|
|
|
tokio::task::yield_now().await;
|
|
|
|
|
|
|
|
// The crawler only activates immediately in tests that use mempool debug mode
|
|
|
|
let mempool_crawler_task_handle = mempool::Crawler::spawn(
|
|
|
|
&config.mempool,
|
|
|
|
peer_set,
|
|
|
|
mempool.clone(),
|
|
|
|
sync_status,
|
|
|
|
chain_tip_change,
|
|
|
|
);
|
|
|
|
|
|
|
|
let syncer_task_handle = tokio::spawn(syncer.sync().in_current_span());
|
2022-06-20 17:59:51 -07:00
|
|
|
|
2021-11-30 13:04:32 -08:00
|
|
|
info!("spawned initial Zebra tasks");
|
2021-10-07 03:46:37 -07:00
|
|
|
|
2022-01-11 09:11:35 -08:00
|
|
|
// TODO: put tasks into an ongoing FuturesUnordered and a startup FuturesUnordered?
|
2021-10-07 03:46:37 -07:00
|
|
|
|
2022-01-11 09:11:35 -08:00
|
|
|
// ongoing tasks
|
2022-03-02 16:39:47 -08:00
|
|
|
pin!(rpc_task_handle);
|
2022-04-11 22:06:29 -07:00
|
|
|
pin!(rpc_tx_queue_task_handle);
|
2022-01-11 09:11:35 -08:00
|
|
|
pin!(syncer_task_handle);
|
2022-04-11 22:06:29 -07:00
|
|
|
pin!(block_gossip_task_handle);
|
2021-11-19 15:02:56 -08:00
|
|
|
pin!(mempool_crawler_task_handle);
|
|
|
|
pin!(mempool_queue_checker_task_handle);
|
|
|
|
pin!(tx_gossip_task_handle);
|
2022-02-12 15:43:12 -08:00
|
|
|
pin!(progress_task_handle);
|
2023-04-28 07:13:21 -07:00
|
|
|
pin!(end_of_support_task_handle);
|
2021-10-08 04:59:46 -07:00
|
|
|
|
2021-11-19 15:02:56 -08:00
|
|
|
// startup tasks
|
2023-02-20 21:30:29 -08:00
|
|
|
let BackgroundTaskHandles {
|
|
|
|
mut groth16_download_handle,
|
|
|
|
mut state_checkpoint_verify_handle,
|
|
|
|
} = consensus_task_handles;
|
|
|
|
|
2021-11-19 15:02:56 -08:00
|
|
|
let groth16_download_handle_fused = (&mut groth16_download_handle).fuse();
|
|
|
|
pin!(groth16_download_handle_fused);
|
2023-02-20 21:30:29 -08:00
|
|
|
|
|
|
|
let state_checkpoint_verify_handle_fused = (&mut state_checkpoint_verify_handle).fuse();
|
|
|
|
pin!(state_checkpoint_verify_handle_fused);
|
|
|
|
|
2022-06-20 17:59:51 -07:00
|
|
|
let old_databases_task_handle_fused = (&mut old_databases_task_handle).fuse();
|
|
|
|
pin!(old_databases_task_handle_fused);
|
2021-10-18 12:23:21 -07:00
|
|
|
|
2021-11-19 15:02:56 -08:00
|
|
|
// Wait for tasks to finish
|
|
|
|
let exit_status = loop {
|
|
|
|
let mut exit_when_task_finishes = true;
|
|
|
|
|
|
|
|
let result = select! {
|
2022-03-02 16:39:47 -08:00
|
|
|
rpc_result = &mut rpc_task_handle => {
|
|
|
|
rpc_result
|
|
|
|
.expect("unexpected panic in the rpc task");
|
|
|
|
info!("rpc task exited");
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2022-04-11 22:06:29 -07:00
|
|
|
rpc_tx_queue_result = &mut rpc_tx_queue_task_handle => {
|
|
|
|
rpc_tx_queue_result
|
|
|
|
.expect("unexpected panic in the rpc transaction queue task");
|
|
|
|
info!("rpc transaction queue task exited");
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2022-01-11 09:11:35 -08:00
|
|
|
sync_result = &mut syncer_task_handle => sync_result
|
|
|
|
.expect("unexpected panic in the syncer task")
|
2021-11-19 15:02:56 -08:00
|
|
|
.map(|_| info!("syncer task exited")),
|
|
|
|
|
2022-01-11 09:11:35 -08:00
|
|
|
block_gossip_result = &mut block_gossip_task_handle => block_gossip_result
|
2021-11-19 15:02:56 -08:00
|
|
|
.expect("unexpected panic in the chain tip block gossip task")
|
|
|
|
.map(|_| info!("chain tip block gossip task exited"))
|
|
|
|
.map_err(|e| eyre!(e)),
|
|
|
|
|
|
|
|
mempool_crawl_result = &mut mempool_crawler_task_handle => mempool_crawl_result
|
|
|
|
.expect("unexpected panic in the mempool crawler")
|
|
|
|
.map(|_| info!("mempool crawler task exited"))
|
|
|
|
.map_err(|e| eyre!(e)),
|
|
|
|
|
|
|
|
mempool_queue_result = &mut mempool_queue_checker_task_handle => mempool_queue_result
|
|
|
|
.expect("unexpected panic in the mempool queue checker")
|
|
|
|
.map(|_| info!("mempool queue checker task exited"))
|
|
|
|
.map_err(|e| eyre!(e)),
|
|
|
|
|
|
|
|
tx_gossip_result = &mut tx_gossip_task_handle => tx_gossip_result
|
|
|
|
.expect("unexpected panic in the transaction gossip task")
|
|
|
|
.map(|_| info!("transaction gossip task exited"))
|
|
|
|
.map_err(|e| eyre!(e)),
|
|
|
|
|
2023-04-13 01:42:17 -07:00
|
|
|
// The progress task runs forever, unless it panics.
|
|
|
|
// So we don't need to provide an exit status for it.
|
2022-02-12 15:43:12 -08:00
|
|
|
progress_result = &mut progress_task_handle => {
|
2023-04-13 01:42:17 -07:00
|
|
|
info!("chain progress task exited");
|
2022-02-12 15:43:12 -08:00
|
|
|
progress_result
|
|
|
|
.expect("unexpected panic in the chain progress task");
|
|
|
|
}
|
|
|
|
|
2023-04-28 07:13:21 -07:00
|
|
|
end_of_support_result = &mut end_of_support_task_handle => end_of_support_result
|
|
|
|
.expect("unexpected panic in the end of support task")
|
|
|
|
.map(|_| info!("end of support task exited")),
|
|
|
|
|
|
|
|
|
2021-11-19 15:02:56 -08:00
|
|
|
// Unlike other tasks, we expect the download task to finish while Zebra is running.
|
|
|
|
groth16_download_result = &mut groth16_download_handle_fused => {
|
|
|
|
groth16_download_result
|
|
|
|
.unwrap_or_else(|_| panic!(
|
|
|
|
"unexpected panic in the Groth16 pre-download and check task. {}",
|
|
|
|
zebra_consensus::groth16::Groth16Parameters::failure_hint())
|
|
|
|
);
|
|
|
|
|
|
|
|
exit_when_task_finishes = false;
|
|
|
|
Ok(())
|
|
|
|
}
|
2022-06-20 17:59:51 -07:00
|
|
|
|
2023-02-20 21:30:29 -08:00
|
|
|
// We also expect the state checkpoint verify task to finish.
|
|
|
|
state_checkpoint_verify_result = &mut state_checkpoint_verify_handle_fused => {
|
|
|
|
state_checkpoint_verify_result
|
|
|
|
.unwrap_or_else(|_| panic!(
|
|
|
|
"unexpected panic checking previous state followed the best chain"));
|
|
|
|
|
|
|
|
exit_when_task_finishes = false;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
// And the old databases task should finish while Zebra is running.
|
2022-06-20 17:59:51 -07:00
|
|
|
old_databases_result = &mut old_databases_task_handle_fused => {
|
|
|
|
old_databases_result
|
|
|
|
.unwrap_or_else(|_| panic!(
|
|
|
|
"unexpected panic deleting old database directories"));
|
|
|
|
|
|
|
|
exit_when_task_finishes = false;
|
|
|
|
Ok(())
|
|
|
|
}
|
2021-11-19 15:02:56 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
// Stop Zebra if a task finished and returned an error,
|
|
|
|
// or if an ongoing task exited.
|
|
|
|
if let Err(err) = result {
|
|
|
|
break Err(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
if exit_when_task_finishes {
|
|
|
|
break Ok(());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
info!("exiting Zebra because an ongoing task exited: stopping other tasks");
|
|
|
|
|
|
|
|
// ongoing tasks
|
2022-04-11 22:06:29 -07:00
|
|
|
rpc_task_handle.abort();
|
|
|
|
rpc_tx_queue_task_handle.abort();
|
2022-01-11 09:11:35 -08:00
|
|
|
syncer_task_handle.abort();
|
|
|
|
block_gossip_task_handle.abort();
|
2021-11-19 15:02:56 -08:00
|
|
|
mempool_crawler_task_handle.abort();
|
|
|
|
mempool_queue_checker_task_handle.abort();
|
|
|
|
tx_gossip_task_handle.abort();
|
2022-04-11 22:06:29 -07:00
|
|
|
progress_task_handle.abort();
|
2023-04-28 07:13:21 -07:00
|
|
|
end_of_support_task_handle.abort();
|
2021-11-19 15:02:56 -08:00
|
|
|
|
|
|
|
// startup tasks
|
|
|
|
groth16_download_handle.abort();
|
2023-02-20 21:30:29 -08:00
|
|
|
state_checkpoint_verify_handle.abort();
|
2022-06-20 17:59:51 -07:00
|
|
|
old_databases_task_handle.abort();
|
2021-11-19 15:02:56 -08:00
|
|
|
|
2022-11-10 06:51:53 -08:00
|
|
|
// Wait until the RPC server shuts down.
|
|
|
|
// This can take around 150 seconds.
|
|
|
|
//
|
|
|
|
// Without this shutdown, Zebra's RPC unit tests sometimes crashed with memory errors.
|
|
|
|
if let Some(rpc_server) = rpc_server {
|
|
|
|
rpc_server.shutdown_blocking();
|
|
|
|
}
|
|
|
|
|
2021-11-19 15:02:56 -08:00
|
|
|
exit_status
|
2020-06-15 17:07:55 -07:00
|
|
|
}
|
2022-02-02 14:44:15 -08:00
|
|
|
|
|
|
|
/// Returns the bound for the state service buffer,
|
|
|
|
/// based on the configurations of the services that use the state concurrently.
|
|
|
|
fn state_buffer_bound() -> usize {
|
2023-06-06 23:03:42 -07:00
|
|
|
let config = APPLICATION.config();
|
2022-02-02 14:44:15 -08:00
|
|
|
|
2022-07-06 07:13:57 -07:00
|
|
|
// Ignore the checkpoint verify limit, because it is very large.
|
|
|
|
//
|
2022-02-02 14:44:15 -08:00
|
|
|
// TODO: do we also need to account for concurrent use across services?
|
|
|
|
// we could multiply the maximum by 3/2, or add a fixed constant
|
2022-07-06 07:13:57 -07:00
|
|
|
[
|
|
|
|
config.sync.download_concurrency_limit,
|
|
|
|
config.sync.full_verify_concurrency_limit,
|
|
|
|
inbound::downloads::MAX_INBOUND_CONCURRENCY,
|
|
|
|
mempool::downloads::MAX_INBOUND_CONCURRENCY,
|
|
|
|
]
|
|
|
|
.into_iter()
|
|
|
|
.max()
|
|
|
|
.unwrap()
|
2022-02-02 14:44:15 -08:00
|
|
|
}
|
2020-06-15 17:07:55 -07:00
|
|
|
}
|
|
|
|
|
2020-06-16 11:02:01 -07:00
|
|
|
impl Runnable for StartCmd {
|
2019-08-29 14:46:54 -07:00
|
|
|
/// Start the application.
|
|
|
|
fn run(&self) {
|
2020-07-31 23:15:26 -07:00
|
|
|
info!("Starting zebrad");
|
2023-06-06 23:03:42 -07:00
|
|
|
let rt = APPLICATION
|
|
|
|
.state()
|
|
|
|
.components_mut()
|
2019-12-13 14:25:14 -08:00
|
|
|
.get_downcast_mut::<TokioComponent>()
|
2019-09-09 13:05:42 -07:00
|
|
|
.expect("TokioComponent should be available")
|
|
|
|
.rt
|
2020-01-13 09:54:27 -08:00
|
|
|
.take();
|
|
|
|
|
2020-08-05 16:35:56 -07:00
|
|
|
rt.expect("runtime should not already be taken")
|
|
|
|
.run(self.start());
|
2021-12-21 18:07:52 -08:00
|
|
|
|
|
|
|
info!("stopping zebrad");
|
2019-08-29 14:46:54 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-16 11:02:01 -07:00
|
|
|
impl config::Override<ZebradConfig> for StartCmd {
|
2019-08-29 14:46:54 -07:00
|
|
|
// Process the given command line options, overriding settings from
|
|
|
|
// a configuration file using explicit flags taken from command-line
|
|
|
|
// arguments.
|
2019-09-09 13:05:42 -07:00
|
|
|
fn override_config(&self, mut config: ZebradConfig) -> Result<ZebradConfig, FrameworkError> {
|
|
|
|
if !self.filters.is_empty() {
|
2020-06-04 19:34:06 -07:00
|
|
|
config.tracing.filter = Some(self.filters.join(","));
|
2019-08-29 14:46:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(config)
|
|
|
|
}
|
|
|
|
}
|