mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
fix(codec): fix last field compilation check (#3543)
This commit is contained in:
@ -58,7 +58,12 @@ fn generate_from_compact(fields: &FieldList, ident: &Ident, is_zstd: bool) -> To
|
||||
// it's hard to figure out with derive_macro which types have bytes::Bytes fields.
|
||||
//
|
||||
// This removes the requirement of the field to be placed last in the struct.
|
||||
known_types.append(&mut vec!["TransactionKind", "AccessList", "Signature"]);
|
||||
known_types.append(&mut vec![
|
||||
"TransactionKind",
|
||||
"AccessList",
|
||||
"Signature",
|
||||
"CheckpointBlockRange",
|
||||
]);
|
||||
|
||||
// let mut handle = FieldListHandler::new(fields);
|
||||
let is_enum = fields.iter().any(|field| matches!(field, FieldTypes::EnumVariant(_)));
|
||||
|
||||
@ -116,17 +116,26 @@ impl<'a> StructHandler<'a> {
|
||||
format_ident!("specialized_from_compact")
|
||||
};
|
||||
|
||||
// ! Be careful before changing the following assert ! Especially if the type does not
|
||||
// implement proptest tests.
|
||||
//
|
||||
// The limitation of the last placed field applies to fields with potentially large sizes,
|
||||
// like the `Transaction` field. These fields may have inner "Bytes" fields, sometimes even
|
||||
// nested further, making it impossible to check with `proc_macro`. The goal is to place
|
||||
// such fields as the last ones, so we don't need to store their length separately. Instead,
|
||||
// we can simply read them until the end of the buffer.
|
||||
//
|
||||
// However, certain types don't require this approach because they don't contain inner
|
||||
// "Bytes" fields. For these types, we can add them to a "known_types" list so it doesn't
|
||||
// trigger this error. These types can handle their own deserialization without
|
||||
// relying on the length provided by the higher-level deserializer. For example, a
|
||||
// type "T" with two "u64" fields doesn't need the length parameter from
|
||||
// "T::from_compact(buf, len)" since the length of "u64" is known internally (bitpacked).
|
||||
assert!(
|
||||
known_types.contains(&ftype.as_str()) ||
|
||||
is_flag_type(ftype) ||
|
||||
self.fields_iterator.peek().map_or(true, |ftypes| {
|
||||
if let FieldTypes::StructField((_, ftype, _, _)) = ftypes {
|
||||
!known_types.contains(&ftype.as_str())
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}),
|
||||
"`{ftype}` field should be placed as the last one since it's not known.
|
||||
self.fields_iterator.peek().is_none(),
|
||||
"`{ftype}` field should be placed as the last one since it's not known.
|
||||
If it's an alias type (which are not supported by proc_macro), be sure to add it to either `known_types` or `get_bit_size` lists in the derive crate."
|
||||
);
|
||||
|
||||
|
||||
@ -23,11 +23,13 @@ pub fn derive_zstd(input: TokenStream) -> TokenStream {
|
||||
compact::derive(input, is_zstd)
|
||||
}
|
||||
|
||||
/// Implements the main codec. If the codec supports it, it will call `derive_arbitrary(..)`.
|
||||
/// This code implements the main codec. If the codec supports it, it will also provide the [derive_arbitrary()] function, which automatically implements arbitrary traits and roundtrip fuzz tests.
|
||||
///
|
||||
/// If you prefer to manually implement the arbitrary traits, you can still use the [add_arbitrary_tests()] function to add arbitrary fuzz tests.
|
||||
///
|
||||
/// Example usage:
|
||||
/// * `#[main_codec(rlp)]`: will implement `derive_arbitrary(rlp)` or `derive_arbitrary(compact, rlp)`, if `compact` is the `main_codec`.
|
||||
/// * `#[main_codec(no_arbitrary)]`: will skip `derive_arbitrary`
|
||||
/// * `#[main_codec(no_arbitrary)]`: will skip `derive_arbitrary` (both trait implementations and tests)
|
||||
#[proc_macro_attribute]
|
||||
#[rustfmt::skip]
|
||||
#[allow(unreachable_code)]
|
||||
|
||||
Reference in New Issue
Block a user