grin_util/
lib.rs

1// Copyright 2021 The Grin Developers
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//! Logging, as well as various low-level utilities that factor Rust
16//! patterns that are frequent within the grin codebase.
17
18#![deny(non_upper_case_globals)]
19#![deny(non_camel_case_types)]
20#![deny(non_snake_case)]
21#![deny(unused_mut)]
22#![warn(missing_docs)]
23
24#[macro_use]
25extern crate log;
26#[macro_use]
27extern crate lazy_static;
28#[macro_use]
29extern crate serde_derive;
30// Re-export so only has to be included once
31pub use parking_lot::{Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard};
32
33// Re-export so only has to be included once
34pub use secp256k1zkp as secp;
35
36// Logging related
37pub mod logger;
38pub use crate::logger::{init_logger, init_test_logger};
39
40// Static secp instance
41pub mod secp_static;
42pub use crate::secp_static::static_secp_instance;
43
44pub mod types;
45pub use crate::types::ZeroingString;
46
47pub mod macros;
48
49// other utils
50#[allow(unused_imports)]
51use std::ops::Deref;
52use std::sync::atomic::{AtomicBool, Ordering};
53use std::sync::Arc;
54mod hex;
55pub use crate::hex::*;
56
57/// File util
58pub mod file;
59/// Compress and decompress zip bz2 archives
60pub mod zip;
61
62mod rate_counter;
63pub use crate::rate_counter::RateCounter;
64
65/// Encapsulation of a RwLock<Option<T>> for one-time initialization.
66/// This implementation will purposefully fail hard if not used
67/// properly, for example if not initialized before being first used
68/// (borrowed).
69#[derive(Clone)]
70pub struct OneTime<T> {
71	/// The inner value.
72	inner: Arc<RwLock<Option<T>>>,
73}
74
75impl<T> OneTime<T>
76where
77	T: Clone,
78{
79	/// Builds a new uninitialized OneTime.
80	pub fn new() -> OneTime<T> {
81		OneTime {
82			inner: Arc::new(RwLock::new(None)),
83		}
84	}
85
86	/// Initializes the OneTime, should only be called once after construction.
87	/// Will panic (via assert) if called more than once.
88	pub fn init(&self, value: T) {
89		self.set(value, false);
90	}
91
92	/// Allows the one time to be set again with an override.
93	pub fn set(&self, value: T, is_override: bool) {
94		let mut inner = self.inner.write();
95		if !is_override {
96			assert!(inner.is_none());
97		}
98		*inner = Some(value);
99	}
100
101	/// Borrows the OneTime, should only be called after initialization.
102	/// Will panic (via expect) if called before initialization.
103	pub fn borrow(&self) -> T {
104		let inner = self.inner.read();
105		inner
106			.clone()
107			.expect("Cannot borrow one_time before initialization.")
108	}
109
110	/// Has this OneTime been initialized?
111	pub fn is_init(&self) -> bool {
112		self.inner.read().is_some()
113	}
114}
115
116/// Encode an utf8 string to a base64 string
117pub fn to_base64(s: &str) -> String {
118	base64::encode(s)
119}
120
121/// Global stopped/paused state shared across various subcomponents of Grin.
122///
123/// "Stopped" allows a clean shutdown of the Grin server.
124/// "Paused" is used in some tests to allow nodes to reach steady state etc.
125///
126pub struct StopState {
127	stopped: AtomicBool,
128	paused: AtomicBool,
129}
130
131impl StopState {
132	/// Create a new stop_state in default "running" state.
133	pub fn new() -> StopState {
134		StopState {
135			stopped: AtomicBool::new(false),
136			paused: AtomicBool::new(false),
137		}
138	}
139
140	/// Check if we are stopped.
141	pub fn is_stopped(&self) -> bool {
142		self.stopped.load(Ordering::Relaxed)
143	}
144
145	/// Check if we are paused.
146	pub fn is_paused(&self) -> bool {
147		self.paused.load(Ordering::Relaxed)
148	}
149
150	/// Stop the server.
151	pub fn stop(&self) {
152		self.stopped.store(true, Ordering::Relaxed)
153	}
154
155	/// Pause the server (only used in tests).
156	pub fn pause(&self) {
157		self.paused.store(true, Ordering::Relaxed)
158	}
159
160	/// Resume a paused server (only used in tests).
161	pub fn resume(&self) {
162		self.paused.store(false, Ordering::Relaxed)
163	}
164}