mirror of
https://github.com/signalapp/libsignal.git
synced 2026-04-25 17:25:18 +02:00
Upgrade to Rust 1.88
This commit is contained in:
@@ -40,7 +40,7 @@ resolver = "2" # so that our dev-dependency features don't leak into products
|
||||
version = "0.86.14"
|
||||
authors = ["Signal Messenger LLC"]
|
||||
license = "AGPL-3.0-only"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.88"
|
||||
|
||||
[workspace.lints.clippy]
|
||||
# Prefer TryFrom between integers unless truncation is desired.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
v0.86.14
|
||||
|
||||
- TypeScript: Fix accidentally-lax typing for the non-deprecated overload of `Net.setRemoteConfig`.
|
||||
- Upgrade MSRV to 1.88
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ name = "attest"
|
||||
version = "0.1.0"
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.88"
|
||||
edition = "2024"
|
||||
|
||||
[lints]
|
||||
|
||||
@@ -93,16 +93,15 @@ pub fn verify_remote_attestation(
|
||||
let attestation = attest(evidence_bytes, endorsement_bytes, current_time)?;
|
||||
|
||||
// 4. Verify the status of the Intel® SGX TCB described in the chain.
|
||||
if let TcbStanding::SWHardeningNeeded { advisory_ids } = attestation.tcb_standing {
|
||||
if advisory_ids
|
||||
if let TcbStanding::SWHardeningNeeded { advisory_ids } = attestation.tcb_standing
|
||||
&& advisory_ids
|
||||
.iter()
|
||||
.any(|id| !acceptable_sw_advisories.contains(&id.as_str()))
|
||||
{
|
||||
return Err(Error::new(format!(
|
||||
"TCB contains unmitigated unaccepted advisory ids: {advisory_ids:?}"
|
||||
))
|
||||
.into());
|
||||
}
|
||||
{
|
||||
return Err(Error::new(format!(
|
||||
"TCB contains unmitigated unaccepted advisory ids: {advisory_ids:?}"
|
||||
))
|
||||
.into());
|
||||
}
|
||||
|
||||
// 5. Verify the enclave measurements in the Quote reflect an enclave identity expected.
|
||||
|
||||
@@ -106,10 +106,12 @@ impl TryFrom<&[u8]> for SgxEndorsements {
|
||||
|
||||
let (offsets, data) = src.split_at(offsets_required_size);
|
||||
|
||||
// TODO: Use as_chunks instead at MSRV 1.88.
|
||||
let (offsets, offsets_remainder) = offsets.as_chunks::<{ std::mem::size_of::<u32>() }>();
|
||||
// offsets_required_size is a multiple of std::mem::size_of::<u32>
|
||||
assert!(offsets_remainder.is_empty());
|
||||
let offsets = offsets
|
||||
.chunks_exact(4)
|
||||
.map(|d| u32::from_le_bytes(d.try_into().expect("correct size")) as usize)
|
||||
.iter()
|
||||
.map(|d| u32::from_le_bytes(*d) as usize)
|
||||
.collect::<Vec<usize>>();
|
||||
|
||||
validate_offsets(&offsets, data)?;
|
||||
|
||||
@@ -72,14 +72,11 @@ pub fn ValidatingMac_Initialize(
|
||||
}
|
||||
let incremental = Incremental::new(hmac, chunk_size as usize);
|
||||
const MAC_SIZE: usize = <Digest as OutputSizeUser>::OutputSize::USIZE;
|
||||
// TODO: When we reach an MSRV of 1.88, we can use as_chunks instead.
|
||||
let macs = digests.chunks_exact(MAC_SIZE);
|
||||
if !macs.remainder().is_empty() {
|
||||
let (macs, macs_remainder) = digests.as_chunks::<MAC_SIZE>();
|
||||
if !macs_remainder.is_empty() {
|
||||
return None;
|
||||
}
|
||||
Some(ValidatingMac(Some(incremental.validating(macs.map(
|
||||
|chunk| <&[u8; MAC_SIZE]>::try_from(chunk).expect("split into correct size already"),
|
||||
)))))
|
||||
Some(ValidatingMac(Some(incremental.validating(macs.iter()))))
|
||||
}
|
||||
|
||||
#[bridge_fn]
|
||||
|
||||
@@ -1073,7 +1073,11 @@ fn GroupSendEndorsementsResponse_IssueDeterministic(
|
||||
key_pair: &[u8],
|
||||
randomness: &[u8; RANDOMNESS_LEN],
|
||||
) -> Vec<u8> {
|
||||
assert!(concatenated_group_member_ciphertexts.len() % UUID_CIPHERTEXT_LEN == 0);
|
||||
assert!(
|
||||
concatenated_group_member_ciphertexts
|
||||
.len()
|
||||
.is_multiple_of(UUID_CIPHERTEXT_LEN)
|
||||
);
|
||||
let user_id_ciphertexts = concatenated_group_member_ciphertexts
|
||||
.chunks_exact(UUID_CIPHERTEXT_LEN)
|
||||
.map(|serialized| {
|
||||
@@ -1142,7 +1146,11 @@ fn GroupSendEndorsementsResponse_ReceiveAndCombineWithCiphertexts(
|
||||
let response = zkgroup::deserialize::<GroupSendEndorsementsResponse>(response_bytes)
|
||||
.expect("should have been parsed previously");
|
||||
|
||||
assert!(concatenated_group_member_ciphertexts.len() % UUID_CIPHERTEXT_LEN == 0);
|
||||
assert!(
|
||||
concatenated_group_member_ciphertexts
|
||||
.len()
|
||||
.is_multiple_of(UUID_CIPHERTEXT_LEN)
|
||||
);
|
||||
let local_user_index = concatenated_group_member_ciphertexts
|
||||
.chunks_exact(UUID_CIPHERTEXT_LEN)
|
||||
.position(|serialized| serialized == local_user_ciphertext)
|
||||
|
||||
@@ -1063,21 +1063,15 @@ impl<A: ResultTypeInfo, B: ResultTypeInfo> ResultTypeInfo for (A, B) {
|
||||
}
|
||||
|
||||
impl<A: ResultTypeInfo, B: ResultTypeInfo> ResultTypeInfo for Option<(A, B)>
|
||||
// We can simplify this when our MSRV is 1.88, when pointers become Default.
|
||||
// Meanwhile, we'll rely on the fact that every C type is zeroable.
|
||||
where
|
||||
A::ResultType: zerocopy::FromZeros,
|
||||
B::ResultType: zerocopy::FromZeros,
|
||||
A::ResultType: Default,
|
||||
B::ResultType: Default,
|
||||
{
|
||||
type ResultType = OptionalPairOf<A::ResultType, B::ResultType>;
|
||||
|
||||
fn convert_into(self) -> SignalFfiResult<Self::ResultType> {
|
||||
let Some(value) = self else {
|
||||
return Ok(OptionalPairOf {
|
||||
present: false,
|
||||
first: zerocopy::FromZeros::new_zeroed(),
|
||||
second: zerocopy::FromZeros::new_zeroed(),
|
||||
});
|
||||
return Ok(OptionalPairOf::default());
|
||||
};
|
||||
Ok(OptionalPairOf {
|
||||
present: true,
|
||||
|
||||
@@ -27,7 +27,9 @@ impl HsmEnclaveClient {
|
||||
return Err(hsm_enclave::Error::InvalidPublicKeyError);
|
||||
}
|
||||
if trusted_code_hashes.is_empty()
|
||||
|| trusted_code_hashes.len() % hsm_enclave::CODE_HASH_SIZE != 0
|
||||
|| !trusted_code_hashes
|
||||
.len()
|
||||
.is_multiple_of(hsm_enclave::CODE_HASH_SIZE)
|
||||
{
|
||||
return Err(hsm_enclave::Error::InvalidCodeHashError);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ use std::sync::Arc;
|
||||
|
||||
use libsignal_protocol::{ServiceId, ServiceIdFixedWidthBinaryBytes};
|
||||
use rayon::iter::ParallelIterator as _;
|
||||
use rayon::slice::ParallelSlice as _;
|
||||
|
||||
use crate::*;
|
||||
|
||||
@@ -39,11 +38,8 @@ impl<'a> ServiceIdSequence<'a> {
|
||||
Self(input)
|
||||
}
|
||||
|
||||
fn parse_single_chunk(chunk: &[u8]) -> ServiceId {
|
||||
ServiceId::parse_from_service_id_fixed_width_binary(
|
||||
chunk.try_into().expect("correctly split"),
|
||||
)
|
||||
.expect(concat!(
|
||||
fn parse_single_chunk(chunk: &ServiceIdFixedWidthBinaryBytes) -> ServiceId {
|
||||
ServiceId::parse_from_service_id_fixed_width_binary(chunk).expect(concat!(
|
||||
"input should be a concatenated list of Service-Id-FixedWidthBinary, ",
|
||||
"but one ServiceId was invalid"
|
||||
))
|
||||
@@ -51,25 +47,29 @@ impl<'a> ServiceIdSequence<'a> {
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for ServiceIdSequence<'a> {
|
||||
type IntoIter = std::iter::Map<std::slice::ChunksExact<'a, u8>, fn(&[u8]) -> ServiceId>;
|
||||
type IntoIter = std::iter::Map<
|
||||
std::slice::Iter<'a, [u8; 17]>,
|
||||
for<'b> fn(&'b ServiceIdFixedWidthBinaryBytes) -> ServiceId,
|
||||
>;
|
||||
type Item = ServiceId;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
// TODO: Use as_chunks when we reach MSRV 1.88.
|
||||
self.0
|
||||
.chunks_exact(Self::SERVICE_ID_FIXED_WIDTH_BINARY_LEN)
|
||||
.map(Self::parse_single_chunk)
|
||||
self.0.as_chunks().0.iter().map(Self::parse_single_chunk)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> rayon::iter::IntoParallelIterator for ServiceIdSequence<'a> {
|
||||
type Iter = rayon::iter::Map<rayon::slice::ChunksExact<'a, u8>, fn(&[u8]) -> ServiceId>;
|
||||
type Iter = rayon::iter::Map<
|
||||
rayon::slice::Iter<'a, ServiceIdFixedWidthBinaryBytes>,
|
||||
for<'b> fn(&'b ServiceIdFixedWidthBinaryBytes) -> ServiceId,
|
||||
>;
|
||||
type Item = ServiceId;
|
||||
|
||||
fn into_par_iter(self) -> Self::Iter {
|
||||
// TODO: Use as_chunks when we reach MSRV 1.88.
|
||||
self.0
|
||||
.par_chunks_exact(Self::SERVICE_ID_FIXED_WIDTH_BINARY_LEN)
|
||||
.as_chunks()
|
||||
.0
|
||||
.into_par_iter()
|
||||
.map(Self::parse_single_chunk)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "libsignal-net"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.88"
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "libsignal-net-infra"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.88"
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
|
||||
@@ -104,12 +104,11 @@ impl<S> From<HandshakeError<S>> for FailedHandshakeReason {
|
||||
// If we specifically have an *SSL* error, check if it's an *X509* error underneath.
|
||||
// (But not X509VerifyError::INVALID_CALL, which means we're not in the right state to
|
||||
// query for verification errors.)
|
||||
if code == boring_signal::ssl::ErrorCode::SSL {
|
||||
if let Some(cert_error_code) = value.ssl().and_then(|ssl| ssl.verify_result().err()) {
|
||||
if cert_error_code != boring_signal::x509::X509VerifyError::INVALID_CALL {
|
||||
return Self::Cert(cert_error_code);
|
||||
}
|
||||
}
|
||||
if code == boring_signal::ssl::ErrorCode::SSL
|
||||
&& let Some(cert_error_code) = value.ssl().and_then(|ssl| ssl.verify_result().err())
|
||||
&& cert_error_code != boring_signal::x509::X509VerifyError::INVALID_CALL
|
||||
{
|
||||
return Self::Cert(cert_error_code);
|
||||
}
|
||||
|
||||
Self::OtherBoring(code)
|
||||
|
||||
@@ -143,30 +143,10 @@ pub trait RouteProvider {
|
||||
/// The routes must be produced in the order in which connection attempts
|
||||
/// should be made. The iterator is allowed to borrow from `self` as an
|
||||
/// optimization.
|
||||
///
|
||||
/// Why is `context` a `&` instead of a `&mut`? Because as of Jan 2025,
|
||||
/// there's no way to prevent the lifetime in the type of `context` from
|
||||
/// being captured in the opaque return type. That's important because there
|
||||
/// are some implementations of this trait where it's necessary to combine
|
||||
/// the output of two different comprising providers. If `context` was a
|
||||
/// `&mut` the first call's exclusive borrow for its entire lifetime would
|
||||
/// prevent the second call from being able to use the same `context`.
|
||||
///
|
||||
/// There are two potential ways we could work around this:
|
||||
///
|
||||
/// 1. Use the new precise-capture syntax introduced in Rust 1.82, and
|
||||
/// stabilized for use in traits in Rust 1.87.
|
||||
///
|
||||
/// 2. Introduce a named associated type that only captures `'s`, not `'c`.
|
||||
/// This works now, but would require all returned iterator types to be
|
||||
/// named. That would prevent us from using `Iterator::map` and other
|
||||
/// combinators, or require any uses be `Box`ed and those tradeoffs
|
||||
/// aren't (currently) worth the imprecision.
|
||||
// TODO: when our MSRV >= 1.87, use precise captures and make context &mut.
|
||||
fn routes<'s>(
|
||||
fn routes<'s, C: RouteProviderContext>(
|
||||
&'s self,
|
||||
context: &impl RouteProviderContext,
|
||||
) -> impl Iterator<Item = Self::Route> + 's;
|
||||
context: &mut C,
|
||||
) -> impl Iterator<Item = Self::Route> + use<'s, C, Self>;
|
||||
}
|
||||
|
||||
/// Context parameter passed to [`RouteProvider::routes`].
|
||||
@@ -175,7 +155,7 @@ pub trait RouteProvider {
|
||||
/// implementer can use to make decisions about what routes to emit.
|
||||
pub trait RouteProviderContext {
|
||||
/// Returns a uniformly random [`usize`].
|
||||
fn random_usize(&self) -> usize;
|
||||
fn random_usize(&mut self) -> usize;
|
||||
}
|
||||
|
||||
/// A hostname in a route that can later be resolved to IP addresses.
|
||||
@@ -586,13 +566,13 @@ fn pull_next_route_delay<F>(connects_in_progress: &FuturesUnordered<F>) -> Durat
|
||||
PER_CONNECTION_WAIT_DURATION * connections_factor
|
||||
}
|
||||
|
||||
impl<R: RouteProvider> RouteProvider for &R {
|
||||
impl<'a, R: RouteProvider> RouteProvider for &'a R {
|
||||
type Route = R::Route;
|
||||
|
||||
fn routes<'s>(
|
||||
fn routes<'s, C: RouteProviderContext>(
|
||||
&'s self,
|
||||
context: &impl RouteProviderContext,
|
||||
) -> impl Iterator<Item = Self::Route> + 's {
|
||||
context: &mut C,
|
||||
) -> impl Iterator<Item = Self::Route> + use<'s, 'a, C, R> {
|
||||
R::routes(self, context)
|
||||
}
|
||||
}
|
||||
@@ -646,10 +626,10 @@ pub mod testutils {
|
||||
impl<R: Clone> RouteProvider for Vec<R> {
|
||||
type Route = R;
|
||||
|
||||
fn routes<'s>(
|
||||
fn routes<'s, C: RouteProviderContext>(
|
||||
&'s self,
|
||||
_context: &impl RouteProviderContext,
|
||||
) -> impl Iterator<Item = Self::Route> + 's {
|
||||
_context: &mut C,
|
||||
) -> impl Iterator<Item = Self::Route> + use<'s, R, C> {
|
||||
self.iter().cloned()
|
||||
}
|
||||
}
|
||||
@@ -673,7 +653,7 @@ pub mod testutils {
|
||||
}
|
||||
|
||||
impl RouteProviderContext for FakeContext {
|
||||
fn random_usize(&self) -> usize {
|
||||
fn random_usize(&mut self) -> usize {
|
||||
UniformUsize::sample_single_inclusive(0, usize::MAX, &mut self.rng.borrow_mut())
|
||||
.expect("non-empty range")
|
||||
}
|
||||
@@ -775,7 +755,7 @@ mod test {
|
||||
},
|
||||
};
|
||||
|
||||
let routes = RouteProvider::routes(&provider, &FakeContext::new()).collect_vec();
|
||||
let routes = RouteProvider::routes(&provider, &mut FakeContext::new()).collect_vec();
|
||||
|
||||
let expected_routes = vec![
|
||||
WebSocketRoute {
|
||||
@@ -896,7 +876,7 @@ mod test {
|
||||
inner: direct_provider,
|
||||
};
|
||||
|
||||
let routes = provider.routes(&FakeContext::new()).collect_vec();
|
||||
let routes = provider.routes(&mut FakeContext::new()).collect_vec();
|
||||
|
||||
assert_eq!(
|
||||
routes,
|
||||
@@ -958,7 +938,7 @@ mod test {
|
||||
inner: direct_provider,
|
||||
};
|
||||
|
||||
let routes = provider.routes(&FakeContext::new()).collect_vec();
|
||||
let routes = provider.routes(&mut FakeContext::new()).collect_vec();
|
||||
|
||||
let expected_routes = vec![
|
||||
TlsRoute {
|
||||
|
||||
@@ -113,10 +113,10 @@ impl DomainFrontRouteProvider {
|
||||
impl RouteProvider for DomainFrontRouteProvider {
|
||||
type Route = HttpsTlsRoute<TlsRoute<TcpRoute<UnresolvedHost>>>;
|
||||
|
||||
fn routes<'s>(
|
||||
fn routes<'s, C: RouteProviderContext>(
|
||||
&'s self,
|
||||
context: &impl RouteProviderContext,
|
||||
) -> impl Iterator<Item = Self::Route> + 's {
|
||||
context: &mut C,
|
||||
) -> impl Iterator<Item = Self::Route> + use<'s, C> {
|
||||
let Self {
|
||||
fronts,
|
||||
http_version,
|
||||
@@ -174,10 +174,10 @@ where
|
||||
F: RouteProvider<Route = HttpsTlsRoute<P::Route>>,
|
||||
{
|
||||
type Route = HttpsTlsRoute<P::Route>;
|
||||
fn routes<'s>(
|
||||
fn routes<'s, C: RouteProviderContext>(
|
||||
&'s self,
|
||||
context: &impl RouteProviderContext,
|
||||
) -> impl Iterator<Item = Self::Route> + 's {
|
||||
context: &mut C,
|
||||
) -> impl Iterator<Item = Self::Route> + use<'s, C, F, P> {
|
||||
let Self {
|
||||
direct_host_header,
|
||||
direct_http_version,
|
||||
@@ -274,7 +274,7 @@ mod test {
|
||||
},
|
||||
};
|
||||
|
||||
let routes = provider.routes(&FakeContext::new()).collect_vec();
|
||||
let routes = provider.routes(&mut FakeContext::new()).collect_vec();
|
||||
|
||||
assert_eq!(
|
||||
routes,
|
||||
|
||||
@@ -45,10 +45,10 @@ pub struct Map<R, F>(R, F);
|
||||
impl<R: RouteProvider, F: Fn(R::Route) -> T, T> RouteProvider for Map<R, F> {
|
||||
type Route = T;
|
||||
|
||||
fn routes<'s>(
|
||||
fn routes<'s, C: RouteProviderContext>(
|
||||
&'s self,
|
||||
context: &impl RouteProviderContext,
|
||||
) -> impl Iterator<Item = Self::Route> + 's {
|
||||
context: &mut C,
|
||||
) -> impl Iterator<Item = Self::Route> + use<'s, C, R, F, T> {
|
||||
self.0.routes(context).map(&self.1)
|
||||
}
|
||||
}
|
||||
@@ -59,10 +59,10 @@ pub struct Filter<R, F>(R, F);
|
||||
impl<R: RouteProvider, F: Fn(&R::Route) -> bool> RouteProvider for Filter<R, F> {
|
||||
type Route = R::Route;
|
||||
|
||||
fn routes<'s>(
|
||||
fn routes<'s, C: RouteProviderContext>(
|
||||
&'s self,
|
||||
context: &impl RouteProviderContext,
|
||||
) -> impl Iterator<Item = Self::Route> + 's {
|
||||
context: &mut C,
|
||||
) -> impl Iterator<Item = Self::Route> + use<'s, C, R, F> {
|
||||
self.0.routes(context).filter(&self.1)
|
||||
}
|
||||
}
|
||||
@@ -75,10 +75,10 @@ pub struct EmptyProvider<R> {
|
||||
impl<R> RouteProvider for EmptyProvider<R> {
|
||||
type Route = R;
|
||||
|
||||
fn routes<'s>(
|
||||
fn routes<'s, C: RouteProviderContext>(
|
||||
&'s self,
|
||||
_context: &impl RouteProviderContext,
|
||||
) -> impl Iterator<Item = Self::Route> + 's {
|
||||
_context: &mut C,
|
||||
) -> impl Iterator<Item = Self::Route> + use<'s, C, R> {
|
||||
std::iter::empty()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,10 +307,10 @@ where
|
||||
{
|
||||
type Route = R;
|
||||
|
||||
fn routes<'s>(
|
||||
fn routes<'s, C: RouteProviderContext>(
|
||||
&'s self,
|
||||
context: &impl RouteProviderContext,
|
||||
) -> impl Iterator<Item = Self::Route> + 's {
|
||||
context: &mut C,
|
||||
) -> impl Iterator<Item = Self::Route> + use<'s, C, D, R> {
|
||||
let Self { inner, mode } = self;
|
||||
let original_routes = inner.routes(context);
|
||||
match mode {
|
||||
|
||||
@@ -70,10 +70,10 @@ impl DirectTcpRouteProvider {
|
||||
impl RouteProvider for DirectTcpRouteProvider {
|
||||
type Route = TcpRoute<UnresolvedHost>;
|
||||
|
||||
fn routes<'s>(
|
||||
fn routes<'s, C: RouteProviderContext>(
|
||||
&'s self,
|
||||
_context: &impl RouteProviderContext,
|
||||
) -> impl Iterator<Item = Self::Route> + 's {
|
||||
_context: &mut C,
|
||||
) -> impl Iterator<Item = Self::Route> + use<'s, C> {
|
||||
let Self {
|
||||
dns_hostname,
|
||||
port,
|
||||
|
||||
@@ -64,10 +64,10 @@ pub(crate) trait SetAlpn {
|
||||
impl<P: RouteProvider> RouteProvider for TlsRouteProvider<P> {
|
||||
type Route = TlsRoute<P::Route>;
|
||||
|
||||
fn routes<'s>(
|
||||
fn routes<'s, C: RouteProviderContext>(
|
||||
&'s self,
|
||||
context: &impl RouteProviderContext,
|
||||
) -> impl Iterator<Item = Self::Route> + 's {
|
||||
context: &mut C,
|
||||
) -> impl Iterator<Item = Self::Route> + use<'s, C, P> {
|
||||
let Self {
|
||||
sni,
|
||||
certs,
|
||||
|
||||
@@ -44,10 +44,10 @@ impl<P> WebSocketProvider<P> {
|
||||
impl<P: RouteProvider> RouteProvider for WebSocketProvider<P> {
|
||||
type Route = WebSocketRoute<P::Route>;
|
||||
|
||||
fn routes<'s>(
|
||||
fn routes<'s, C: RouteProviderContext>(
|
||||
&'s self,
|
||||
context: &impl RouteProviderContext,
|
||||
) -> impl Iterator<Item = Self::Route> + 's {
|
||||
context: &mut C,
|
||||
) -> impl Iterator<Item = Self::Route> + use<'s, C, P> {
|
||||
self.inner.routes(context).map(|route| WebSocketRoute {
|
||||
inner: route,
|
||||
fragment: self.fragment.clone(),
|
||||
|
||||
@@ -142,20 +142,17 @@ impl TryFrom<ClientResponse> for LookupResponse {
|
||||
debug_permits_used,
|
||||
} = response;
|
||||
|
||||
if e164_pni_aci_triples.len() % LookupResponseEntry::SERIALIZED_LEN != 0 {
|
||||
let (record_chunks, record_remainder) =
|
||||
e164_pni_aci_triples.as_chunks::<{ LookupResponseEntry::SERIALIZED_LEN }>();
|
||||
|
||||
if !record_remainder.is_empty() {
|
||||
return Err(CdsiProtocolError::InvalidNumberOfBytes {
|
||||
actual_length: e164_pni_aci_triples.len(),
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Use as_chunks when we reach MSRV 1.88.
|
||||
let records = e164_pni_aci_triples
|
||||
.chunks(LookupResponseEntry::SERIALIZED_LEN)
|
||||
.flat_map(|record| {
|
||||
LookupResponseEntry::try_parse_from(
|
||||
record.try_into().expect("chunk size is correct"),
|
||||
)
|
||||
})
|
||||
let records = record_chunks
|
||||
.iter()
|
||||
.flat_map(LookupResponseEntry::try_parse_from)
|
||||
.collect();
|
||||
|
||||
Ok(Self {
|
||||
|
||||
@@ -441,10 +441,10 @@ impl Responder {
|
||||
pub fn send_response(self, status: StatusCode) -> Result<(), SendError> {
|
||||
let Self { id, tx } = self;
|
||||
|
||||
if let Some(tx) = tx.upgrade() {
|
||||
if let Ok(()) = tx.send(OutgoingResponse { id, status }) {
|
||||
return Ok(());
|
||||
}
|
||||
if let Some(tx) = tx.upgrade()
|
||||
&& let Ok(()) = tx.send(OutgoingResponse { id, status })
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
Err(SendError::Disconnected(DisconnectedReason::SocketClosed {
|
||||
|
||||
@@ -506,13 +506,13 @@ impl<TC> ConnectionResources<'_, TC> {
|
||||
post_route_change_connect_timeout,
|
||||
transport_connector,
|
||||
attempts_record,
|
||||
route_provider_context,
|
||||
mut route_provider_context,
|
||||
} = connect_state
|
||||
.lock()
|
||||
.expect("not poisoned")
|
||||
.prepare_snapshot();
|
||||
|
||||
let routes = routes.routes(&route_provider_context).collect_vec();
|
||||
let routes = routes.routes(&mut route_provider_context).collect_vec();
|
||||
|
||||
log::info!(
|
||||
"[{log_tag}] starting connection attempt with {} routes",
|
||||
@@ -649,7 +649,7 @@ where
|
||||
post_route_change_connect_timeout,
|
||||
transport_connector,
|
||||
attempts_record,
|
||||
route_provider_context,
|
||||
mut route_provider_context,
|
||||
} = connect_state
|
||||
.lock()
|
||||
.expect("not poisoned")
|
||||
@@ -660,7 +660,7 @@ where
|
||||
should: true,
|
||||
inner: r,
|
||||
})
|
||||
.routes(&route_provider_context)
|
||||
.routes(&mut route_provider_context)
|
||||
.collect_vec();
|
||||
|
||||
log::info!(
|
||||
@@ -777,7 +777,7 @@ where
|
||||
struct RouteProviderContextImpl(UnwrapErr<OsRng>);
|
||||
|
||||
impl RouteProviderContext for RouteProviderContextImpl {
|
||||
fn random_usize(&self) -> usize {
|
||||
fn random_usize(&mut self) -> usize {
|
||||
// OsRng is zero-sized, so we're not losing random values by copying it.
|
||||
let mut owned_rng: UnwrapErr<OsRng> = self.0;
|
||||
assert_eq_size_val!(owned_rng, ());
|
||||
|
||||
@@ -251,10 +251,10 @@ impl From<WebSocketServiceConnectError> for Error {
|
||||
response,
|
||||
received_at: _,
|
||||
} => {
|
||||
if response.status() == http::StatusCode::TOO_MANY_REQUESTS {
|
||||
if let Some(retry_later) = extract_retry_later(response.headers()) {
|
||||
return Self::RateLimited(retry_later);
|
||||
}
|
||||
if response.status() == http::StatusCode::TOO_MANY_REQUESTS
|
||||
&& let Some(retry_later) = extract_retry_later(response.headers())
|
||||
{
|
||||
return Self::RateLimited(retry_later);
|
||||
}
|
||||
Self::WebSocket(WebSocketError::Http(response))
|
||||
}
|
||||
|
||||
@@ -962,7 +962,7 @@ mod test {
|
||||
},
|
||||
override_nagle_algorithm,
|
||||
);
|
||||
let routes = route_provider.routes(&FakeContext::new()).collect_vec();
|
||||
let routes = route_provider.routes(&mut FakeContext::new()).collect_vec();
|
||||
|
||||
let expected_direct_route = HttpsTlsRoute {
|
||||
fragment: HttpRouteFragment {
|
||||
|
||||
@@ -9,7 +9,7 @@ version = "0.7.0"
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.88"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
@@ -19,15 +19,13 @@ impl Proof {
|
||||
/// Returns `None` if the input is invalid. This does not run in constant
|
||||
/// time!
|
||||
pub fn from_slice(bytes: &[u8]) -> Option<Self> {
|
||||
// TODO: use as_chunks instead once we reach MSRV 1.88.
|
||||
let chunks = bytes.chunks_exact(32);
|
||||
if !chunks.remainder().is_empty() {
|
||||
let (chunks, chunks_remainder) = bytes.as_chunks::<32>();
|
||||
if !chunks_remainder.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let mut array_chunks = chunks.map(|chunk| {
|
||||
let chunk = chunk.try_into().expect("chunk size is exact");
|
||||
Option::from(Scalar::from_canonical_bytes(chunk))
|
||||
});
|
||||
let mut array_chunks = chunks
|
||||
.iter()
|
||||
.map(|chunk| Option::from(Scalar::from_canonical_bytes(*chunk)));
|
||||
|
||||
let challenge = array_chunks.next()??;
|
||||
if array_chunks.len() > 256 {
|
||||
|
||||
@@ -204,13 +204,11 @@ impl Statement {
|
||||
sho2.absorb_and_ratchet(message); // M
|
||||
let blinding_scalar_bytes = sho2.squeeze_and_ratchet(g1.len() * 64);
|
||||
|
||||
// TODO: use as_chunks once we reach MSRV 1.88.
|
||||
let nonce: G1 = blinding_scalar_bytes
|
||||
.chunks_exact(64)
|
||||
.map(|chunk| {
|
||||
let chunk = chunk.try_into().expect("correct width");
|
||||
Scalar::from_bytes_mod_order_wide(chunk)
|
||||
})
|
||||
.as_chunks::<64>()
|
||||
.0
|
||||
.iter()
|
||||
.map(Scalar::from_bytes_mod_order_wide)
|
||||
.collect();
|
||||
|
||||
// Commitment from nonce by applying homomorphism F: commitment = F(nonce)
|
||||
|
||||
Reference in New Issue
Block a user