grpc: run authenticate's PBKDF2 verify off the engine lock
All checks were successful
CI / check (push) Successful in 3m54s

The Authenticate RPC held the engine Mutex across scram verify_plain, which at
production iteration counts (1.2M) is ~0.8s of PBKDF2 on the async reactor —
freezing the whole daemon (IRC link, gossip, every RPC) for the duration and
serializing all logins. Fetch the verifier under the lock (cheap), then run
verify_plain on spawn_blocking, lock released. 6 concurrent logins: 823ms (was
~4460ms serialized). set_password/register already offload this way; drop the
now-unused authority_authenticate.
This commit is contained in:
Jean Chevronnet 2026-07-16 18:40:30 +00:00
parent 2e92f75a90
commit 63fc2fb2c0
No known key found for this signature in database
2 changed files with 23 additions and 5 deletions

View file

@ -47,8 +47,13 @@ impl Engine {
status
}
pub fn authority_authenticate(&self, name: &str, password: &str) -> Option<String> {
self.db.authenticate(name, password).map(str::to_string)
/// The account's canonical name and its SHA-256 verifier (owned), so a caller
/// can run the PBKDF2 verify OFF the engine lock. At production iteration
/// counts that derivation is ~1s of CPU — never run it while holding the lock
/// (it would freeze the whole daemon); fetch here, then `scram::verify_plain`
/// on a blocking thread.
pub fn scram_verifier(&self, name: &str) -> Option<(String, String)> {
self.db.scram_lookup(name, "SCRAM-SHA-256").map(|(a, v)| (a.to_string(), v.to_string()))
}
pub fn authority_set_password(&mut self, account: &str, creds: Option<db::Credentials>) -> AuthorityStatus {