diem_config/config/
safety_rules_config.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4// Copyright 2021 Conflux Foundation. All rights reserved.
5// Conflux is free software and distributed under GNU General Public License.
6// See http://www.gnu.org/licenses/
7
8use crate::{
9    config::{LoggerConfig, SecureBackend},
10    keys::ConfigKey,
11};
12use cfx_types::U256;
13use diem_crypto::Uniform;
14use diem_types::{
15    network_address::NetworkAddress,
16    validator_config::{ConsensusPrivateKey, ConsensusVRFPrivateKey},
17    PeerId,
18};
19use rand::rngs::StdRng;
20use serde::{Deserialize, Serialize};
21use std::{
22    net::{SocketAddr, ToSocketAddrs},
23    path::PathBuf,
24};
25
26#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
27#[serde(default, deny_unknown_fields)]
28pub struct SafetyRulesConfig {
29    pub backend: SecureBackend,
30    pub logger: LoggerConfig,
31    pub service: SafetyRulesService,
32    pub test: Option<SafetyRulesTestConfig>,
33    pub verify_vote_proposal_signature: bool,
34    pub export_consensus_key: bool,
35    // Read/Write/Connect networking operation timeout in milliseconds.
36    pub network_timeout_ms: u64,
37    pub enable_cached_safety_data: bool,
38
39    pub vrf_private_key: Option<ConfigKey<ConsensusVRFPrivateKey>>,
40    pub vrf_proposal_threshold: U256,
41}
42
43impl Default for SafetyRulesConfig {
44    fn default() -> Self {
45        Self {
46            backend: SecureBackend::OnDiskStorage(Default::default()),
47            logger: LoggerConfig::default(),
48            service: SafetyRulesService::Thread,
49            test: None,
50            verify_vote_proposal_signature: true,
51            export_consensus_key: false,
52            // Default value of 30 seconds for a timeout
53            network_timeout_ms: 30_000,
54            enable_cached_safety_data: true,
55            vrf_private_key: None,
56            vrf_proposal_threshold: U256::MAX,
57        }
58    }
59}
60
61impl SafetyRulesConfig {
62    pub fn set_data_dir(&mut self, data_dir: PathBuf) {
63        if let SecureBackend::OnDiskStorage(backend) = &mut self.backend {
64            backend.set_data_dir(data_dir);
65        }
66    }
67}
68
69/// Defines how safety rules should be executed
70#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
71#[serde(rename_all = "snake_case", tag = "type")]
72pub enum SafetyRulesService {
73    /// This runs safety rules in the same thread as event processor
74    Local,
75    /// This is the production, separate service approach
76    Process(RemoteService),
77    /// This runs safety rules in the same thread as event processor but data
78    /// is passed through the light weight RPC (serializer)
79    Serializer,
80    /// This creates a separate thread to run safety rules, it is similar to a
81    /// fork / exec style
82    Thread,
83}
84
85#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
86#[serde(deny_unknown_fields)]
87pub struct RemoteService {
88    pub server_address: NetworkAddress,
89}
90
91impl RemoteService {
92    pub fn server_address(&self) -> SocketAddr {
93        self.server_address
94            .to_socket_addrs()
95            .expect("server_address invalid")
96            .next()
97            .expect("server_address invalid")
98    }
99}
100
101#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
102pub struct SafetyRulesTestConfig {
103    pub author: PeerId,
104    pub consensus_key: Option<ConfigKey<ConsensusPrivateKey>>,
105    pub execution_key: Option<ConfigKey<ConsensusPrivateKey>>,
106}
107
108impl SafetyRulesTestConfig {
109    pub fn new(author: PeerId) -> Self {
110        Self {
111            author,
112            consensus_key: None,
113            execution_key: None,
114        }
115    }
116
117    pub fn consensus_key(&mut self, key: ConsensusPrivateKey) {
118        self.consensus_key = Some(ConfigKey::new(key));
119    }
120
121    pub fn execution_key(&mut self, key: ConsensusPrivateKey) {
122        self.execution_key = Some(ConfigKey::new(key));
123    }
124
125    pub fn random_consensus_key(&mut self, rng: &mut StdRng) {
126        let privkey = ConsensusPrivateKey::generate(rng);
127        self.consensus_key =
128            Some(ConfigKey::<ConsensusPrivateKey>::new(privkey));
129    }
130
131    pub fn random_execution_key(&mut self, rng: &mut StdRng) {
132        let privkey = ConsensusPrivateKey::generate(rng);
133        self.execution_key =
134            Some(ConfigKey::<ConsensusPrivateKey>::new(privkey));
135    }
136}