upgrade to Rust 1.70, use `std::sync::OnceLock`

The most notable part of this is that `db::auth` no longer holds a lock
during password hashing operations. That was probably never a great
idea...
This commit is contained in:
Scott Lamb 2023-07-04 13:45:33 -07:00
parent ebcdd76084
commit 028243532a
9 changed files with 91 additions and 138 deletions

View File

@ -11,7 +11,7 @@ jobs:
name: Rust ${{ matrix.rust }}
strategy:
matrix:
rust: [ "stable", "1.65", "nightly" ]
rust: [ "stable", "1.70", "nightly" ]
include:
- rust: nightly
extra_args: "--features nightly --benches"

View File

@ -14,7 +14,7 @@ even on minor releases, e.g. `0.7.5` -> `0.7.6`.
## unreleased
* new log formats using `tracing`. This will allow richer context information.
* bump minimum Rust version to 1.65.
* bump minimum Rust version to 1.70.
* expect camelCase in `moonfire-nvr.toml` file, for consistency with the JSON
API. You'll need to adjust your config file when upgrading.
* use Retina 0.4.5.

131
server/Cargo.lock generated
View File

@ -38,6 +38,12 @@ dependencies = [
"memchr",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
@ -191,9 +197,9 @@ checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
[[package]]
name = "cc"
version = "1.0.78"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]]
name = "cfg-if"
@ -203,13 +209,13 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.23"
version = "0.4.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-integer",
"num-traits",
"time 0.1.45",
"wasm-bindgen",
@ -226,16 +232,6 @@ dependencies = [
"inout",
]
[[package]]
name = "codespan-reporting"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
dependencies = [
"termcolor",
"unicode-width",
]
[[package]]
name = "constant_time_eq"
version = "0.2.4"
@ -250,9 +246,9 @@ checksum = "396de984970346b0d9e93d1415082923c679e5ae5c3ee3dcbd104f5610af126b"
[[package]]
name = "core-foundation-sys"
version = "0.8.3"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]]
name = "cpufeatures"
@ -352,50 +348,6 @@ dependencies = [
"xi-unicode",
]
[[package]]
name = "cxx"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5add3fc1717409d029b20c5b6903fc0c0b02fa6741d820054f4a2efa5e5816fd"
dependencies = [
"cc",
"cxxbridge-flags",
"cxxbridge-macro",
"link-cplusplus",
]
[[package]]
name = "cxx-build"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4c87959ba14bc6fbc61df77c3fcfe180fc32b93538c4f1031dd802ccb5f2ff0"
dependencies = [
"cc",
"codespan-reporting",
"once_cell",
"proc-macro2",
"quote",
"scratch",
"syn 1.0.107",
]
[[package]]
name = "cxxbridge-flags"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69a3e162fde4e594ed2b07d0f83c6c67b745e7f28ce58c6df5e6b6bef99dfb59"
[[package]]
name = "cxxbridge-macro"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e7e2adeb6a0d4a282e581096b06e1791532b7d576dcde5ccd9382acf55db8e6"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.107",
]
[[package]]
name = "darling"
version = "0.14.2"
@ -903,26 +855,25 @@ dependencies = [
[[package]]
name = "iana-time-zone"
version = "0.1.53"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"winapi",
"windows",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.1"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cxx",
"cxx-build",
"cc",
]
[[package]]
@ -1039,15 +990,6 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "link-cplusplus"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
dependencies = [
"cc",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.3"
@ -1170,7 +1112,6 @@ dependencies = [
"nix",
"num-rational",
"odds",
"once_cell",
"pretty-hex",
"protobuf",
"protobuf-codegen",
@ -1217,7 +1158,6 @@ dependencies = [
"nix",
"nom",
"num-rational",
"once_cell",
"password-hash",
"protobuf",
"reffers",
@ -1852,12 +1792,6 @@ dependencies = [
"cipher",
]
[[package]]
name = "scratch"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2"
[[package]]
name = "scrypt"
version = "0.10.0"
@ -2097,15 +2031,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
[[package]]
name = "thiserror"
version = "1.0.38"
@ -2646,21 +2571,21 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.42.0"

View File

@ -5,7 +5,7 @@ authors = ["Scott Lamb <slamb@slamb.org>"]
edition = "2021"
resolver = "2"
license-file = "../LICENSE.txt"
rust-version = "1.65"
rust-version = "1.70"
[features]
@ -27,6 +27,7 @@ blake3 = "1.0.0"
bpaf = { git = "https://github.com/pacak/bpaf.git", rev = "905ab7166dd59e89bebbd3364e14b203ee57dba4", features = ["autocomplete", "bright-color", "derive"]}
bytes = "1"
byteorder = "1.0"
chrono = "0.4.23"
cursive = "0.20.0"
db = { package = "moonfire-db", path = "db" }
failure = "0.1.1"
@ -58,15 +59,13 @@ tokio-stream = "0.1.5"
tokio-tungstenite = "0.18.0"
toml = "0.5"
tracing = { version = "0.1", features = ["log"] }
url = "2.1.1"
uuid = { version = "1.1.2", features = ["serde", "std", "v4"] }
once_cell = "1.17.0"
tracing-subscriber = { version = "0.3.16", features = ["env-filter", "json"] }
tracing-core = "0.1.30"
tracing-log = "0.1.3"
chrono = "0.4.23"
ulid = "1.0.0"
tracing-futures = { version = "0.2.5", features = ["futures-03", "std-future"] }
tracing-log = "0.1.3"
ulid = "1.0.0"
url = "2.1.1"
uuid = { version = "1.1.2", features = ["serde", "std", "v4"] }
[dev-dependencies]
mp4 = { git = "https://github.com/scottlamb/mp4-rust", branch = "moonfire" }

View File

@ -5,6 +5,7 @@ authors = ["Scott Lamb <slamb@slamb.org>"]
readme = "../README.md"
edition = "2021"
license-file = "../../LICENSE.txt"
rust-version = "1.70"
[features]
nightly = []
@ -24,6 +25,7 @@ fnv = "1.0"
futures = "0.3"
h264-reader = "0.6.0"
hashlink = "0.8.1"
itertools = "0.10.0"
libc = "0.2"
nix = "0.26.1"
num-rational = { version = "0.4.0", default-features = false, features = ["std"] }
@ -40,12 +42,10 @@ smallvec = "1.0"
tempfile = "3.2.0"
time = "0.1"
tokio = { version = "1.24", features = ["macros", "rt-multi-thread", "sync"] }
url = { version = "2.1.1", features = ["serde"] }
uuid = { version = "1.1.2", features = ["serde", "std", "v4"] }
itertools = "0.10.0"
once_cell = "1.17.0"
tracing = "0.1.37"
ulid = "1.0.0"
url = { version = "2.1.1", features = ["serde"] }
uuid = { version = "1.1.2", features = ["serde", "std", "v4"] }
[build-dependencies]
protobuf-codegen = "3.0"

View File

@ -17,17 +17,41 @@ use std::collections::BTreeMap;
use std::fmt;
use std::net::IpAddr;
use std::str::FromStr;
use std::sync::Mutex;
use std::sync::OnceLock;
use tracing::info;
static PARAMS: once_cell::sync::Lazy<Mutex<scrypt::Params>> =
once_cell::sync::Lazy::new(|| Mutex::new(scrypt::Params::recommended()));
/// Wrapper around [`scrypt::Params`].
///
/// `scrypt::Params` does not implement `PartialEq`; so for the benefit of `set_test_config`
/// error handling, keep track of whether these params are the recommended
/// production ones or the cheap test ones.
struct Params {
actual: scrypt::Params,
is_test: bool,
}
static PARAMS: OnceLock<Params> = OnceLock::new();
fn params() -> &'static Params {
PARAMS.get_or_init(|| Params {
actual: scrypt::Params::recommended(),
is_test: false,
})
}
/// For testing only: use fast but insecure hashes.
/// Call via `testutil::init()`.
pub(crate) fn set_test_config() {
let params = scrypt::Params::new(8, 8, 1).unwrap();
*PARAMS.lock().unwrap() = params;
let test_params = scrypt::Params::new(8, 8, 1).expect("test params should be valid");
if let Err(existing_params) = PARAMS.set(Params {
actual: test_params,
is_test: true,
}) {
assert!(
existing_params.is_test,
"set_test_config must be called before any use of the parameters"
);
}
}
#[derive(Debug)]
@ -126,9 +150,9 @@ impl UserChange {
pub fn set_password(&mut self, pwd: String) {
let salt = SaltString::generate(&mut scrypt::password_hash::rand_core::OsRng);
let params = *PARAMS.lock().unwrap();
let params = params();
let hash = scrypt::Scrypt
.hash_password_customized(pwd.as_bytes(), None, None, params, &salt)
.hash_password_customized(pwd.as_bytes(), None, None, params.actual, &salt)
.unwrap();
self.set_password_hash = Some(Some(hash.to_string()));
}

View File

@ -368,7 +368,7 @@ fn confirm_deletion(siv: &mut Cursive, db: &Arc<db::Database>, id: i32, to_delet
for (&stream_id, stream) in l.streams_by_id() {
if stream.camera_id == id {
let Some(dir_id) = stream.sample_file_dir_id else {
continue
continue;
};
let l = zero_limits
.entry(dir_id)

View File

@ -3028,8 +3028,7 @@ mod bench {
}
}
static SERVER: once_cell::sync::Lazy<BenchServer> =
once_cell::sync::Lazy::new(BenchServer::new);
static SERVER: std::sync::OnceLock<BenchServer> = std::sync::OnceLock::new();
#[bench]
fn build_index(b: &mut test::Bencher) {
@ -3063,7 +3062,7 @@ mod bench {
#[bench]
fn serve_generated_bytes(b: &mut test::Bencher) {
testutil::init();
let server = &*SERVER;
let server = server.get_or_init(BenchServer::new);
let p = server.generated_len;
b.bytes = p;
let client = reqwest::Client::new();

View File

@ -226,18 +226,24 @@ mod tests {
}
#[rustfmt::skip]
static SLICES: once_cell::sync::Lazy<Slices<FakeSlice>> = once_cell::sync::Lazy::new(|| {
let mut s = Slices::new();
s.append(FakeSlice { end: 5, name: "a" }).unwrap();
s.append(FakeSlice { end: 5 + 13, name: "b" }).unwrap();
s.append(FakeSlice { end: 5 + 13 + 7, name: "c" }).unwrap();
s.append(FakeSlice { end: 5 + 13 + 7 + 17, name: "d" }).unwrap();
s.append(FakeSlice { end: 5 + 13 + 7 + 17 + 19, name: "e" }).unwrap();
s
});
static SLICES: std::sync::OnceLock<Slices<FakeSlice>> = std::sync::OnceLock::new();
#[rustfmt::skip]
fn slices() -> &'static Slices<FakeSlice> {
SLICES.get_or_init(|| {
let mut s = Slices::new();
s.append(FakeSlice { end: 5, name: "a" }).unwrap();
s.append(FakeSlice { end: 5 + 13, name: "b" }).unwrap();
s.append(FakeSlice { end: 5 + 13 + 7, name: "c" }).unwrap();
s.append(FakeSlice { end: 5 + 13 + 7 + 17, name: "d" }).unwrap();
s.append(FakeSlice { end: 5 + 13 + 7 + 17 + 19, name: "e" }).unwrap();
s
})
}
async fn get_range(r: Range<u64>) -> Vec<FakeChunk> {
Pin::from(SLICES.get_range(&&*SLICES, r))
let slices = slices();
Pin::from(slices.get_range(&slices, r))
.try_collect()
.await
.unwrap()
@ -246,7 +252,7 @@ mod tests {
#[test]
pub fn size() {
testutil::init();
assert_eq!(5 + 13 + 7 + 17 + 19, SLICES.len());
assert_eq!(5 + 13 + 7 + 17 + 19, slices().len());
}
#[tokio::test]