Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into alloy
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelsproul committed Aug 14, 2024
2 parents 0df21e4 + 58cbde5 commit d463c17
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 39 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,19 @@ jobs:
run: cargo test --release
- name: Check all examples, binaries, etc
run: cargo check --all-targets
coverage:
runs-on: ubuntu-latest
name: cargo-tarpaulin
steps:
- uses: actions/checkout@v3
- name: Get latest version of stable Rust
run: rustup update stable
- name: Install cargo-tarpaulin
uses: taiki-e/install-action@cargo-tarpaulin
- name: Check code coverage with cargo-tarpaulin
run: make coverage
- name: Upload to codecov.io
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Cargo.lock
target
cobertura.xml
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# These hacks are required for the test binaries depending on the dynamic library libstd-*.so
# See: https://github.com/rust-lang/cargo/issues/4651
#
# We also need to exclude the derive macro from coverage because it will always show as 0% by
# virtue of executing at compile-time outside the view of Tarpaulin.
coverage:
env LD_LIBRARY_PATH="$(shell rustc --print sysroot)/lib" \
cargo-tarpaulin --workspace --all-features --out xml --exclude tree_hash_derive

.PHONY: coverage
7 changes: 4 additions & 3 deletions tree_hash_derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ categories = ["cryptography::cryptocurrencies"]
proc-macro = true

[dependencies]
syn = "1.0.42"
quote = "1.0.7"
darling = "0.13.0"
syn = "2.0.69"
proc-macro2 = "1.0.23"
quote = "1.0.18"
darling = "0.20.9"
42 changes: 6 additions & 36 deletions tree_hash_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use darling::FromDeriveInput;
use proc_macro::TokenStream;
use quote::quote;
use std::convert::TryInto;
use syn::{parse_macro_input, Attribute, DataEnum, DataStruct, DeriveInput, Meta};
use syn::{parse_macro_input, DataEnum, DataStruct, DeriveInput, Ident};

/// The highest possible union selector value (higher values are reserved for backwards compatible
/// extensions).
Expand Down Expand Up @@ -48,14 +48,14 @@ impl EnumBehaviour {
fn get_hashable_fields(struct_data: &syn::DataStruct) -> Vec<&syn::Ident> {
get_hashable_fields_and_their_caches(struct_data)
.into_iter()
.map(|(ident, _, _)| ident)
.map(|(ident, _)| ident)
.collect()
}

/// Return a Vec of the hashable fields of a struct, and each field's type and optional cache field.
fn get_hashable_fields_and_their_caches(
struct_data: &syn::DataStruct,
) -> Vec<(&syn::Ident, syn::Type, Option<syn::Ident>)> {
) -> Vec<(&syn::Ident, syn::Type)> {
struct_data
.fields
.iter()
Expand All @@ -67,49 +67,19 @@ fn get_hashable_fields_and_their_caches(
.ident
.as_ref()
.expect("tree_hash_derive only supports named struct fields");
let opt_cache_field = get_cache_field_for(f);
Some((ident, f.ty.clone(), opt_cache_field))
Some((ident, f.ty.clone()))
}
})
.collect()
}

/// Parse the cached_tree_hash attribute for a field.
///
/// Extract the cache field name from `#[cached_tree_hash(cache_field_name)]`
///
/// Return `Some(cache_field_name)` if the field has a cached tree hash attribute,
/// or `None` otherwise.
fn get_cache_field_for(field: &syn::Field) -> Option<syn::Ident> {
use syn::{MetaList, NestedMeta};

let parsed_attrs = cached_tree_hash_attr_metas(&field.attrs);
if let [Meta::List(MetaList { nested, .. })] = &parsed_attrs[..] {
nested.iter().find_map(|x| match x {
NestedMeta::Meta(Meta::Path(path)) => path.get_ident().cloned(),
_ => None,
})
} else {
None
}
}

/// Process the `cached_tree_hash` attributes from a list of attributes into structured `Meta`s.
fn cached_tree_hash_attr_metas(attrs: &[Attribute]) -> Vec<Meta> {
attrs
.iter()
.filter(|attr| attr.path.is_ident("cached_tree_hash"))
.flat_map(|attr| attr.parse_meta())
.collect()
}

/// Returns true if some field has an attribute declaring it should not be hashed.
///
/// The field attribute is: `#[tree_hash(skip_hashing)]`
fn should_skip_hashing(field: &syn::Field) -> bool {
field.attrs.iter().any(|attr| {
attr.path.is_ident("tree_hash")
&& attr.tokens.to_string().replace(' ', "") == "(skip_hashing)"
attr.path().is_ident("tree_hash")
&& attr.parse_args::<Ident>().unwrap().to_string() == "skip_hashing"
})
}

Expand Down

0 comments on commit d463c17

Please sign in to comment.