mamanegoryu1

exonum/src/helpers/fabric/maintenance.rs

May 21st, 2020
327
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 6.30 KB | None | 0 0
  1. // Copyright 2019 The Exonum Team
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. //   http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14.  
  15. //! This module implements node maintenance actions.
  16.  
  17. // use std::{collections::HashMap, path::{Path, PathBuf}, str::FromStr};
  18. use std::{
  19.     collections::HashMap,
  20.     path::{Path, PathBuf},
  21. };
  22.  
  23. use super::{
  24.     internal::{CollectedCommand, Command, Feedback},
  25.     Argument, CommandName, Context,
  26. };
  27. use crate::blockchain::Schema;
  28. use crate::helpers::config::ConfigFile;
  29. use crate::node::NodeConfig;
  30. use exonum_merkledb::{Database, DbOptions, RocksDB};
  31. use crate::helpers::fabric::password::{PassInputMethod, SecretKeyType};
  32.  
  33. // Context entry for the path to the node config.
  34. const NODE_CONFIG_PATH: &str = "NODE_CONFIG_PATH";
  35. // Context entry for the path to the database.
  36. const DATABASE_PATH: &str = "DATABASE_PATH";
  37. // Context entry for the type of action to be performed.
  38. const MAINTENANCE_ACTION_PATH: &str = "MAINTENANCE_ACTION_PATH";
  39.  
  40. const CONSENSUS_KEY_PASS_METHOD: &str = "CONSENSUS_KEY_PASS_METHOD";
  41.  
  42. const SERVICE_KEY_PASS_METHOD: &str = "SERVICE_KEY_PASS_METHOD";
  43.  
  44. /// Maintenance command. Supported actions:
  45. ///
  46. /// - `clear-cache` - clear message cache.
  47. #[derive(Debug)]
  48. pub struct Maintenance;
  49.  
  50. impl Maintenance {
  51.     fn node_config(ctx: &Context) -> NodeConfig<PathBuf> {
  52.         let path = ctx
  53.             .arg::<String>(NODE_CONFIG_PATH)
  54.             .unwrap_or_else(|_| panic!("{} not found.", NODE_CONFIG_PATH));
  55.         let run_config: NodeConfig<PathBuf> = ConfigFile::load(path.clone()).expect("Can't load node config file");
  56.  
  57.         let consensus_passphrase = {
  58.             let consensus_pass_method = ctx
  59.                 .arg::<String>(CONSENSUS_KEY_PASS_METHOD)
  60.                 .unwrap_or_else(|_| panic!("{} not found.", NODE_CONFIG_PATH));
  61.  
  62.             PassInputMethod::from_str(&consensus_pass_method)
  63.                 .expect("Incorrect passphrase input method for consensus key.")
  64.                 .get_passphrase(SecretKeyType::Consensus, true)
  65.         };
  66.  
  67.         let service_passphrase = {
  68.             let service_pass_method = ctx
  69.                 .arg::<String>(SERVICE_KEY_PASS_METHOD)
  70.                 .unwrap_or_else(|_| panic!("{} not found.", NODE_CONFIG_PATH));
  71.  
  72.             PassInputMethod::from_str(&service_pass_method)
  73.                 .expect("Incorrect passphrase input method for service key.")
  74.                 .get_passphrase(SecretKeyType::Service, true)
  75.         };
  76.  
  77.         run_config.read_secret_keys(
  78.             &path,
  79.             consensus_passphrase.as_bytes(),
  80.             service_passphrase.as_bytes(),
  81.         )
  82.     }
  83.  
  84.     fn database(ctx: &Context, options: &DbOptions) -> Box<dyn Database> {
  85.         let path = ctx
  86.             .arg::<String>(DATABASE_PATH)
  87.             .unwrap_or_else(|_| panic!("{} not found.", DATABASE_PATH));
  88.         Box::new(RocksDB::open(Path::new(&path), options).expect("Can't load database file"))
  89.     }
  90.  
  91.     fn clear_cache(context: &Context) {
  92.         info!("Clearing node cache");
  93.  
  94.         let config = Self::node_config(context);
  95.         let db = Self::database(context, &config.database);
  96.         let fork = db.fork();
  97.         let schema = Schema::new(&fork);
  98.         schema.consensus_messages_cache().clear();
  99. //        schema.peers_cache().clear(); //todo(mike): check it
  100.  
  101.         db.merge_sync(fork.into_patch()).expect("Can't clear cache");
  102.  
  103.         info!("Cache cleared successfully");
  104.     }
  105. }
  106.  
  107. impl Command for Maintenance {
  108.     fn args(&self) -> Vec<Argument> {
  109.         vec![
  110.             Argument::new_named(
  111.                 NODE_CONFIG_PATH,
  112.                 true,
  113.                 "Path to node configuration file.",
  114.                 "c",
  115.                 "node-config",
  116.                 false,
  117.             ),
  118.             Argument::new_named(
  119.                 DATABASE_PATH,
  120.                 true,
  121.                 "Use database with the given path.",
  122.                 "d",
  123.                 "db-path",
  124.                 false,
  125.             ),
  126.             Argument::new_named(
  127.                 MAINTENANCE_ACTION_PATH,
  128.                 true,
  129.                 "Action to be performed during maintenance.",
  130.                 "a",
  131.                 "action",
  132.                 false,
  133.             ),
  134.             Argument::new_named(
  135.                 CONSENSUS_KEY_PASS_METHOD,
  136.                 false,
  137.                 "Passphrase entry method for consensus key.\n\
  138.                 Possible values are: stdin, env{:ENV_VAR_NAME}, pass:PASSWORD (default: stdin)\n\
  139.                 If ENV_VAR_NAME is not specified $EXONUM_CONSENSUS_PASS is used",
  140.                 None,
  141.                 "consensus-key-pass",
  142.                 false,
  143.             ),
  144.             Argument::new_named(
  145.                 SERVICE_KEY_PASS_METHOD,
  146.                 false,
  147.                 "Passphrase entry method for service key.\n\
  148.                 Possible values are: stdin, env{:ENV_VAR_NAME}, pass:PASSWORD (default: stdin)\n\
  149.                 If ENV_VAR_NAME is not specified $EXONUM_SERVICE_PASS is used",
  150.                 None,
  151.                 "service-key-pass",
  152.                 false,
  153.             ),
  154.         ]
  155.     }
  156.  
  157.     fn name(&self) -> CommandName {
  158.         "maintenance"
  159.     }
  160.  
  161.     fn about(&self) -> &str {
  162.         "Maintenance module. Available actions: clear-cache."
  163.     }
  164.  
  165.     fn execute(
  166.         &self,
  167.         _commands: &HashMap<CommandName, CollectedCommand>,
  168.         context: Context,
  169.         _: &dyn Fn(Context) -> Context,
  170.     ) -> Feedback {
  171.         let action = context
  172.             .arg::<String>(MAINTENANCE_ACTION_PATH)
  173.             .unwrap_or_else(|_| panic!("{} not found.", MAINTENANCE_ACTION_PATH));
  174.  
  175.         if action == "clear-cache" {
  176.             Self::clear_cache(&context);
  177.         } else {
  178.             println!("Unsupported maintenance action: {}", action);
  179.         }
  180.  
  181.         Feedback::None
  182.     }
  183. }
Add Comment
Please, Sign In to add comment