Skip to content

Commit f8f5b8e

Browse files
committed
feat: Add support for multiple digest functions with backward compatibility
1 parent 45e300c commit f8f5b8e

3 files changed

Lines changed: 63 additions & 3 deletions

File tree

nativelink-store/src/grpc_store.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use nativelink_util::health_utils::HealthStatusIndicator;
4444
use nativelink_util::proto_stream_utils::{
4545
FirstStream, WriteRequestStreamWrapper, WriteState, WriteStateWrapper,
4646
};
47-
use nativelink_util::resource_info::ResourceInfo;
47+
use nativelink_util::resource_info::{ResourceInfo, is_supported_digest_function};
4848
use nativelink_util::retry::{Retrier, RetryResult};
4949
use nativelink_util::store_trait::{StoreDriver, StoreKey, UploadSizeInfo};
5050
use nativelink_util::{default_health_status_indicator, tls_utils};
@@ -278,12 +278,28 @@ impl GrpcStore {
278278
where
279279
R: IntoRequest<ReadRequest>,
280280
{
281+
const IS_UPLOAD_FALSE: bool = false;
282+
283+
let request = self.get_read_request(grpc_request.into_request().into_inner())?;
284+
let resource_name = &request.resource_name;
285+
let resource_info = ResourceInfo::new(resource_name, IS_UPLOAD_FALSE)
286+
.err_tip(|| "Failed to parse resource_name in GrpcStore::read")?;
287+
288+
let digest_function = resource_info.digest_function.as_deref().unwrap_or("sha256");
289+
290+
if !is_supported_digest_function(digest_function) {
291+
return Err(make_input_err!(
292+
"Unsupported digest_function: {} in resource_name '{}'",
293+
digest_function,
294+
resource_name
295+
));
296+
}
297+
281298
error_if!(
282299
matches!(self.store_type, nativelink_config::stores::StoreType::Ac),
283300
"CAS operation on AC store"
284301
);
285302

286-
let request = self.get_read_request(grpc_request.into_request().into_inner())?;
287303
self.perform_request(request, |request| async move {
288304
self.read_internal(request).await
289305
})
@@ -516,6 +532,18 @@ impl StoreDriver for GrpcStore {
516532
keys: &[StoreKey<'_>],
517533
results: &mut [Option<u64>],
518534
) -> Result<(), Error> {
535+
let digest_function = ActiveOriginContext::get_value(&ACTIVE_HASHER_FUNC)
536+
.err_tip(|| "In GrpcStore::has_with_results")?
537+
.map_or_else(default_digest_hasher_func, |v| *v)
538+
.to_string();
539+
540+
if !is_supported_digest_function(&digest_function) {
541+
return Err(make_input_err!(
542+
"Unsupported digest_function: {}",
543+
digest_function
544+
));
545+
}
546+
519547
if matches!(self.store_type, nativelink_config::stores::StoreType::Ac) {
520548
keys.iter()
521549
.zip(results.iter_mut())

nativelink-util/src/resource_info.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ enum State {
206206
OptionalMetadata,
207207
}
208208

209+
pub fn is_supported_digest_function(digest_function: &str) -> bool {
210+
DIGEST_FUNCTIONS.contains(&digest_function.to_lowercase().as_str())
211+
}
212+
209213
// Iterate backwards looking for "(compressed-)blobs", once found, move forward
210214
// populating the output struct. This recursive function utilises the stack to
211215
// temporarily hold the reference to the previous item reducing the need for

nativelink-util/tests/resource_info_test.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use std::borrow::Cow;
1616

1717
use nativelink_macro::nativelink_test;
18-
use nativelink_util::resource_info::ResourceInfo;
18+
use nativelink_util::resource_info::{ResourceInfo, is_supported_digest_function};
1919
use pretty_assertions::assert_eq;
2020

2121
#[nativelink_test]
@@ -707,3 +707,31 @@ async fn write_invalid_size_test() -> Result<(), Box<dyn core::error::Error>> {
707707
assert!(ResourceInfo::new(RESOURCE_NAME, true).is_err());
708708
Ok(())
709709
}
710+
711+
#[nativelink_test]
712+
async fn test_supported_digest_functions() -> Result<(), Box<dyn std::error::Error>> {
713+
assert_eq!(is_supported_digest_function("sha256"), true);
714+
assert_eq!(is_supported_digest_function("sha1"), true);
715+
assert_eq!(is_supported_digest_function("md5"), true);
716+
assert_eq!(is_supported_digest_function("vso"), true);
717+
assert_eq!(is_supported_digest_function("sha384"), true);
718+
assert_eq!(is_supported_digest_function("sha512"), true);
719+
assert_eq!(is_supported_digest_function("murmur3"), true);
720+
assert_eq!(is_supported_digest_function("sha256tree"), true);
721+
assert_eq!(is_supported_digest_function("blake3"), true);
722+
723+
Ok(())
724+
}
725+
726+
#[nativelink_test]
727+
async fn test_unsupported_digest_functions() -> Result<(), Box<dyn std::error::Error>> {
728+
assert_eq!(is_supported_digest_function("sha3"), false);
729+
assert_eq!(
730+
is_supported_digest_function("invalid_digest_function"),
731+
false
732+
);
733+
assert_eq!(is_supported_digest_function("boo"), false);
734+
assert_eq!(is_supported_digest_function("random_hash"), false);
735+
736+
Ok(())
737+
}

0 commit comments

Comments
 (0)