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
|
|
|
//!
|
2021-12-21 18:07:52 -08:00
|
|
|
//! A zebra node consists of the following 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
|
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
|
|
|
//!
|
|
|
|
//! Zebra also has diagnostic support
|
|
|
|
//! * [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)
|
|
|
|
//!
|
|
|
|
//! Some of the diagnostic features are optional, and need to be enabled at compile-time.
|
2020-07-20 21:00:22 -07:00
|
|
|
|
2020-09-18 12:18:22 -07:00
|
|
|
use abscissa_core::{config, Command, FrameworkError, Options, Runnable};
|
|
|
|
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
|
|
|
|
2022-02-22 03:26:29 -08:00
|
|
|
use zebra_rpc::server::RpcServer;
|
|
|
|
|
2020-09-09 12:03:09 -07:00
|
|
|
use crate::{
|
2022-02-28 19:32:32 -08:00
|
|
|
application::app_version,
|
2021-09-08 11:51:17 -07:00
|
|
|
components::{
|
2022-02-02 14:44:15 -08:00
|
|
|
inbound::{self, InboundSetupData},
|
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
|
|
|
|
2019-08-29 14:46:54 -07:00
|
|
|
/// `start` subcommand
|
2022-08-30 02:01:33 -07:00
|
|
|
#[derive(Command, Debug, Options, Default)]
|
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
|
|
|
|
#[options(free, 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> {
|
2020-09-18 12:18:22 -07:00
|
|
|
let config = app_config().clone();
|
2020-06-15 17:07:55 -07:00
|
|
|
|
2020-09-18 12:18:22 -07:00
|
|
|
info!("initializing node state");
|
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
|
|
|
let (_, max_checkpoint_height) = zebra_consensus::chain::init_checkpoint_list(
|
|
|
|
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.
|
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)
|
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
|
|
|
|
Reject connections from outdated peers (#2519)
* Simplify state service initialization in test
Use the test helper function to remove redundant code.
* Create `BestTipHeight` helper type
This type abstracts away the calculation of the best tip height based on
the finalized block height and the best non-finalized chain's tip.
* Add `best_tip_height` field to `StateService`
The receiver endpoint is currently ignored.
* Return receiver endpoint from service constructor
Make it available so that the best tip height can be watched.
* Update finalized height after finalizing blocks
After blocks from the queue are finalized and committed to disk, update
the finalized block height.
* Update best non-finalized height after validation
Update the value of the best non-finalized chain tip block height after
a new block is committed to the non-finalized state.
* Update finalized height after loading from disk
When `FinalizedState` is first created, it loads the state from
persistent storage, and the finalized tip height is updated. Therefore,
the `best_tip_height` must be notified of the initial value.
* Update the finalized height on checkpoint commit
When a checkpointed block is commited, it bypasses the non-finalized
state, so there's an extra place where the finalized height has to be
updated.
* Add `best_tip_height` to `Handshake` service
It can be configured using the `Builder::with_best_tip_height`. It's
currently not used, but it will be used to determine if a connection to
a remote peer should be rejected or not based on that peer's protocol
version.
* Require best tip height to init. `zebra_network`
Without it the handshake service can't properly enforce the minimum
network protocol version from peers. Zebrad obtains the best tip height
endpoint from `zebra_state`, and the test vectors simply use a dummy
endpoint that's fixed at the genesis height.
* Pass `best_tip_height` to proto. ver. negotiation
The protocol version negotiation code will reject connections to peers
if they are using an old protocol version. An old version is determined
based on the current known best chain tip height.
* Handle an optional height in `Version`
Fallback to the genesis height in `None` is specified.
* Reject connections to peers on old proto. versions
Avoid connecting to peers that are on protocol versions that don't
recognize a network update.
* Document why peers on old versions are rejected
Describe why it's a security issue above the check.
* Test if `BestTipHeight` starts with `None`
Check if initially there is no best tip height.
* Test if best tip height is max. of latest values
After applying a list of random updates where each one either sets the
finalized height or the non-finalized height, check that the best tip
height is the maximum of the most recently set finalized height and the
most recently set non-finalized height.
* Add `queue_and_commit_finalized` method
A small refactor to make testing easier. The handling of requests for
committing non-finalized and finalized blocks is now more consistent.
* Add `assert_block_can_be_validated` helper
Refactor to move into a separate method some assertions that are done
before a block is validated. This is to allow moving these assertions
more easily to simplify testing.
* Remove redundant PoW block assertion
It's also checked in
`zebra_state::service::check::block_is_contextually_valid`, and it was
getting in the way of tests that received a gossiped block before
finalizing enough blocks.
* Create a test strategy for test vector chain
Splits a chain loaded from the test vectors in two parts, containing the
blocks to finalize and the blocks to keep in the non-finalized state.
* Test committing blocks update best tip height
Create a mock blockchain state, with a chain of finalized blocks and a
chain of non-finalized blocks. Commit all the blocks appropriately, and
verify that the best tip height is updated.
Co-authored-by: teor <teor@riseup.net>
2021-08-08 16:52:52 -07:00
|
|
|
let (peer_set, address_book) =
|
2021-09-29 09:52:44 -07:00
|
|
|
zebra_network::init(config.network.clone(), inbound, latest_chain_tip.clone()).await;
|
2021-09-13 13:28:07 -07:00
|
|
|
|
2021-11-23 09:42:44 -08:00
|
|
|
info!("initializing verifiers");
|
2022-07-06 07:13:57 -07:00
|
|
|
let (chain_verifier, tx_verifier, mut groth16_download_handle, max_checkpoint_height) =
|
2021-11-23 09:42:44 -08:00
|
|
|
zebra_consensus::chain::init(
|
|
|
|
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(),
|
|
|
|
chain_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
|
|
|
|
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(
|
2022-03-09 17:12:41 -08:00
|
|
|
config.rpc,
|
2022-11-09 16:12:27 -08:00
|
|
|
#[cfg(feature = "getblocktemplate-rpcs")]
|
|
|
|
config.mining,
|
|
|
|
#[cfg(not(feature = "getblocktemplate-rpcs"))]
|
|
|
|
(),
|
2022-03-15 15:29:15 -07:00
|
|
|
app_version(),
|
2022-03-09 17:12:41 -08:00
|
|
|
mempool.clone(),
|
2022-03-15 12:50:28 -07:00
|
|
|
read_only_state_service,
|
2022-11-03 20:57:08 -07:00
|
|
|
chain_verifier.clone(),
|
2022-12-02 03:21:23 -08:00
|
|
|
sync_status.clone(),
|
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
|
|
|
|
2021-11-23 09:42:44 -08:00
|
|
|
let setup_data = InboundSetupData {
|
|
|
|
address_book,
|
|
|
|
block_download_peer_set: peer_set.clone(),
|
|
|
|
block_verifier: chain_verifier,
|
|
|
|
mempool: mempool.clone(),
|
|
|
|
state,
|
2022-02-12 15:43:12 -08:00
|
|
|
latest_chain_tip: latest_chain_tip.clone(),
|
2021-11-23 09:42:44 -08:00
|
|
|
};
|
2020-09-18 12:18:22 -07:00
|
|
|
setup_tx
|
2021-11-23 09:42:44 -08:00
|
|
|
.send(setup_data)
|
2020-09-18 12:18:22 -07:00
|
|
|
.map_err(|_| eyre!("could not send setup data to inbound service"))?;
|
2020-06-15 17:07:55 -07:00
|
|
|
|
2022-01-28 14:12:19 -08:00
|
|
|
let syncer_task_handle = tokio::spawn(syncer.sync().in_current_span());
|
2021-10-07 03:46:37 -07:00
|
|
|
|
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
|
|
|
|
2021-10-13 08:04:49 -07:00
|
|
|
let mempool_crawler_task_handle = mempool::Crawler::spawn(
|
|
|
|
&config.mempool,
|
|
|
|
peer_set.clone(),
|
2021-10-18 12:23:21 -07:00
|
|
|
mempool.clone(),
|
2022-02-12 15:43:12 -08:00
|
|
|
sync_status.clone(),
|
2021-10-13 08:04:49 -07:00
|
|
|
chain_tip_change,
|
|
|
|
);
|
2021-10-08 04:59:46 -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(
|
|
|
|
mempool::gossip_mempool_transaction_id(mempool_transaction_receiver, peer_set)
|
|
|
|
.in_current_span(),
|
|
|
|
);
|
2021-10-07 03:46:37 -07:00
|
|
|
|
2022-02-12 15:43:12 -08:00
|
|
|
let progress_task_handle = tokio::spawn(
|
2022-06-27 19:51:41 -07:00
|
|
|
show_block_chain_progress(config.network.network, latest_chain_tip, sync_status)
|
2022-02-12 15:43:12 -08:00
|
|
|
.in_current_span(),
|
|
|
|
);
|
|
|
|
|
2022-06-20 17:59:51 -07:00
|
|
|
let mut old_databases_task_handle =
|
|
|
|
zebra_state::check_and_delete_old_databases(config.state.clone());
|
|
|
|
|
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);
|
2021-10-08 04:59:46 -07:00
|
|
|
|
2021-11-19 15:02:56 -08:00
|
|
|
// startup tasks
|
|
|
|
let groth16_download_handle_fused = (&mut groth16_download_handle).fuse();
|
|
|
|
pin!(groth16_download_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)),
|
|
|
|
|
2022-02-12 15:43:12 -08:00
|
|
|
progress_result = &mut progress_task_handle => {
|
|
|
|
progress_result
|
|
|
|
.expect("unexpected panic in the chain progress task");
|
|
|
|
info!("chain progress task exited");
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
|
|
// The same for the old databases task, we expect it to finish while Zebra is running.
|
|
|
|
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();
|
2021-11-19 15:02:56 -08:00
|
|
|
|
|
|
|
// startup tasks
|
|
|
|
groth16_download_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 {
|
|
|
|
let config = app_config().clone();
|
|
|
|
|
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");
|
2020-01-13 09:54:27 -08:00
|
|
|
let rt = app_writer()
|
2019-12-13 14:25:14 -08:00
|
|
|
.state_mut()
|
2019-09-09 13:05:42 -07:00
|
|
|
.components
|
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)
|
|
|
|
}
|
|
|
|
}
|