mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: make to_compact borrow (#9488)
Co-authored-by: joshieDo <93316087+joshieDo@users.noreply.github.com>
This commit is contained in:
@ -67,7 +67,7 @@ impl Bytecode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for Bytecode {
|
impl Compact for Bytecode {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -209,7 +209,7 @@ mod tests {
|
|||||||
2,
|
2,
|
||||||
JumpTable::from_slice(&[0]),
|
JumpTable::from_slice(&[0]),
|
||||||
)));
|
)));
|
||||||
let len = bytecode.clone().to_compact(&mut buf);
|
let len = bytecode.to_compact(&mut buf);
|
||||||
assert_eq!(len, 16);
|
assert_eq!(len, 16);
|
||||||
|
|
||||||
let (decoded, remainder) = Bytecode::from_compact(&buf, len);
|
let (decoded, remainder) = Bytecode::from_compact(&buf, len);
|
||||||
|
|||||||
@ -58,7 +58,7 @@ mod tests {
|
|||||||
fn test_roundtrip_conversion_between_log_and_alloy_log(log in arb::<Log>()) {
|
fn test_roundtrip_conversion_between_log_and_alloy_log(log in arb::<Log>()) {
|
||||||
// Convert log to buffer and then create alloy_log from buffer and compare
|
// Convert log to buffer and then create alloy_log from buffer and compare
|
||||||
let mut compacted_log = Vec::<u8>::new();
|
let mut compacted_log = Vec::<u8>::new();
|
||||||
let len = log.clone().to_compact(&mut compacted_log);
|
let len = log.to_compact(&mut compacted_log);
|
||||||
|
|
||||||
let alloy_log = AlloyLog::from_compact(&compacted_log, len).0;
|
let alloy_log = AlloyLog::from_compact(&compacted_log, len).0;
|
||||||
assert_eq!(log, alloy_log.into());
|
assert_eq!(log, alloy_log.into());
|
||||||
|
|||||||
@ -31,7 +31,7 @@ impl From<(B256, U256)> for StorageEntry {
|
|||||||
// and compress second part of the value. If we have compression
|
// and compress second part of the value. If we have compression
|
||||||
// over whole value (Even SubKey) that would mess up fetching of values with seek_by_key_subkey
|
// over whole value (Even SubKey) that would mess up fetching of values with seek_by_key_subkey
|
||||||
impl Compact for StorageEntry {
|
impl Compact for StorageEntry {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
|
|||||||
@ -144,7 +144,7 @@ mod tests {
|
|||||||
// Convert to buffer and then create alloy_access_list from buffer and
|
// Convert to buffer and then create alloy_access_list from buffer and
|
||||||
// compare
|
// compare
|
||||||
let mut compacted_reth_withdrawal = Vec::<u8>::new();
|
let mut compacted_reth_withdrawal = Vec::<u8>::new();
|
||||||
let len = withdrawal.clone().to_compact(&mut compacted_reth_withdrawal);
|
let len = withdrawal.to_compact(&mut compacted_reth_withdrawal);
|
||||||
|
|
||||||
// decode the compacted buffer to AccessList
|
// decode the compacted buffer to AccessList
|
||||||
let alloy_withdrawal = Withdrawal::from_compact(&compacted_reth_withdrawal, len).0;
|
let alloy_withdrawal = Withdrawal::from_compact(&compacted_reth_withdrawal, len).0;
|
||||||
|
|||||||
@ -658,7 +658,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
receipt.clone().to_compact(&mut data);
|
receipt.to_compact(&mut data);
|
||||||
let (decoded, _) = Receipt::from_compact(&data[..], data.len());
|
let (decoded, _) = Receipt::from_compact(&data[..], data.len());
|
||||||
assert_eq!(decoded, receipt);
|
assert_eq!(decoded, receipt);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,7 +73,7 @@ mod tests {
|
|||||||
// Convert access_list to buffer and then create alloy_access_list from buffer and
|
// Convert access_list to buffer and then create alloy_access_list from buffer and
|
||||||
// compare
|
// compare
|
||||||
let mut compacted_reth_access_list = Vec::<u8>::new();
|
let mut compacted_reth_access_list = Vec::<u8>::new();
|
||||||
let len = access_list.clone().to_compact(&mut compacted_reth_access_list);
|
let len = access_list.to_compact(&mut compacted_reth_access_list);
|
||||||
|
|
||||||
// decode the compacted buffer to AccessList
|
// decode the compacted buffer to AccessList
|
||||||
let alloy_access_list = AccessList::from_compact(&compacted_reth_access_list, len).0;
|
let alloy_access_list = AccessList::from_compact(&compacted_reth_access_list, len).0;
|
||||||
|
|||||||
@ -681,7 +681,7 @@ impl From<TxEip7702> for Transaction {
|
|||||||
impl reth_codecs::Compact for Transaction {
|
impl reth_codecs::Compact for Transaction {
|
||||||
// Serializes the TxType to the buffer if necessary, returning 2 bits of the type as an
|
// Serializes the TxType to the buffer if necessary, returning 2 bits of the type as an
|
||||||
// identifier instead of the length.
|
// identifier instead of the length.
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -910,7 +910,7 @@ impl TransactionSignedNoHash {
|
|||||||
|
|
||||||
#[cfg(any(test, feature = "reth-codec"))]
|
#[cfg(any(test, feature = "reth-codec"))]
|
||||||
impl reth_codecs::Compact for TransactionSignedNoHash {
|
impl reth_codecs::Compact for TransactionSignedNoHash {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -2083,7 +2083,7 @@ mod tests {
|
|||||||
fn test_transaction_signed_to_from_compact(tx_signed_no_hash: TransactionSignedNoHash) {
|
fn test_transaction_signed_to_from_compact(tx_signed_no_hash: TransactionSignedNoHash) {
|
||||||
// zstd aware `to_compact`
|
// zstd aware `to_compact`
|
||||||
let mut buff: Vec<u8> = Vec::new();
|
let mut buff: Vec<u8> = Vec::new();
|
||||||
let written_bytes = tx_signed_no_hash.clone().to_compact(&mut buff);
|
let written_bytes = tx_signed_no_hash.to_compact(&mut buff);
|
||||||
let (decoded, _) = TransactionSignedNoHash::from_compact(&buff, written_bytes);
|
let (decoded, _) = TransactionSignedNoHash::from_compact(&buff, written_bytes);
|
||||||
assert_eq!(tx_signed_no_hash, decoded);
|
assert_eq!(tx_signed_no_hash, decoded);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,7 @@ impl Signature {
|
|||||||
|
|
||||||
#[cfg(any(test, feature = "reth-codec"))]
|
#[cfg(any(test, feature = "reth-codec"))]
|
||||||
impl reth_codecs::Compact for Signature {
|
impl reth_codecs::Compact for Signature {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
|
|||||||
@ -138,7 +138,7 @@ impl TryFrom<U64> for TxType {
|
|||||||
|
|
||||||
#[cfg(any(test, feature = "reth-codec"))]
|
#[cfg(any(test, feature = "reth-codec"))]
|
||||||
impl reth_codecs::Compact for TxType {
|
impl reth_codecs::Compact for TxType {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -147,16 +147,16 @@ impl reth_codecs::Compact for TxType {
|
|||||||
Self::Eip2930 => 1,
|
Self::Eip2930 => 1,
|
||||||
Self::Eip1559 => 2,
|
Self::Eip1559 => 2,
|
||||||
Self::Eip4844 => {
|
Self::Eip4844 => {
|
||||||
buf.put_u8(self as u8);
|
buf.put_u8(*self as u8);
|
||||||
COMPACT_EXTENDED_IDENTIFIER_FLAG
|
COMPACT_EXTENDED_IDENTIFIER_FLAG
|
||||||
}
|
}
|
||||||
Self::Eip7702 => {
|
Self::Eip7702 => {
|
||||||
buf.put_u8(self as u8);
|
buf.put_u8(*self as u8);
|
||||||
COMPACT_EXTENDED_IDENTIFIER_FLAG
|
COMPACT_EXTENDED_IDENTIFIER_FLAG
|
||||||
}
|
}
|
||||||
#[cfg(feature = "optimism")]
|
#[cfg(feature = "optimism")]
|
||||||
Self::Deposit => {
|
Self::Deposit => {
|
||||||
buf.put_u8(self as u8);
|
buf.put_u8(*self as u8);
|
||||||
COMPACT_EXTENDED_IDENTIFIER_FLAG
|
COMPACT_EXTENDED_IDENTIFIER_FLAG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,7 +33,7 @@ impl MerkleCheckpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for MerkleCheckpoint {
|
impl Compact for MerkleCheckpoint {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -47,7 +47,7 @@ impl Compact for MerkleCheckpoint {
|
|||||||
|
|
||||||
buf.put_u16(self.walker_stack.len() as u16);
|
buf.put_u16(self.walker_stack.len() as u16);
|
||||||
len += 2;
|
len += 2;
|
||||||
for item in self.walker_stack {
|
for item in &self.walker_stack {
|
||||||
len += item.to_compact(buf);
|
len += item.to_compact(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,7 +393,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
let encoded = checkpoint.clone().to_compact(&mut buf);
|
let encoded = checkpoint.to_compact(&mut buf);
|
||||||
let (decoded, _) = MerkleCheckpoint::from_compact(&buf, encoded);
|
let (decoded, _) = MerkleCheckpoint::from_compact(&buf, encoded);
|
||||||
assert_eq!(decoded, checkpoint);
|
assert_eq!(decoded, checkpoint);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,7 @@ alloy-eips = { workspace = true, default-features = false, features = [
|
|||||||
"arbitrary",
|
"arbitrary",
|
||||||
"serde",
|
"serde",
|
||||||
] }
|
] }
|
||||||
alloy-primitives = { workspace = true, features = ["arbitrary", "serde"] }
|
alloy-primitives = { workspace = true, features = ["arbitrary", "serde", "rand"] }
|
||||||
alloy-consensus = { workspace = true, features = ["arbitrary"] }
|
alloy-consensus = { workspace = true, features = ["arbitrary"] }
|
||||||
test-fuzz.workspace = true
|
test-fuzz.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
|
|||||||
@ -26,7 +26,7 @@ pub fn maybe_generate_tests(args: TokenStream, ast: &DeriveInput) -> TokenStream
|
|||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
let len = field.clone().to_compact(&mut buf);
|
let len = field.clone().to_compact(&mut buf);
|
||||||
let (decoded, _) = super::#type_ident::from_compact(&buf, len);
|
let (decoded, _) = super::#type_ident::from_compact(&buf, len);
|
||||||
assert!(field == decoded);
|
assert!(field == decoded, "maybe_generate_tests::compact");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if arg.to_string() == "rlp" {
|
} else if arg.to_string() == "rlp" {
|
||||||
@ -37,7 +37,7 @@ pub fn maybe_generate_tests(args: TokenStream, ast: &DeriveInput) -> TokenStream
|
|||||||
let len = field.encode(&mut buf);
|
let len = field.encode(&mut buf);
|
||||||
let mut b = &mut buf.as_slice();
|
let mut b = &mut buf.as_slice();
|
||||||
let decoded = super::#type_ident::decode(b).unwrap();
|
let decoded = super::#type_ident::decode(b).unwrap();
|
||||||
assert_eq!(field, decoded);
|
assert_eq!(field, decoded, "maybe_generate_tests::rlp");
|
||||||
// ensure buffer is fully consumed by decode
|
// ensure buffer is fully consumed by decode
|
||||||
assert!(b.is_empty(), "buffer was not consumed entirely");
|
assert!(b.is_empty(), "buffer was not consumed entirely");
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use super::*;
|
|||||||
/// their potential presence.
|
/// their potential presence.
|
||||||
pub(crate) fn generate_flag_struct(
|
pub(crate) fn generate_flag_struct(
|
||||||
ident: &Ident,
|
ident: &Ident,
|
||||||
|
has_lifetime: bool,
|
||||||
fields: &FieldList,
|
fields: &FieldList,
|
||||||
is_zstd: bool,
|
is_zstd: bool,
|
||||||
) -> TokenStream2 {
|
) -> TokenStream2 {
|
||||||
@ -52,15 +53,29 @@ pub(crate) fn generate_flag_struct(
|
|||||||
let docs =
|
let docs =
|
||||||
format!("Fieldset that facilitates compacting the parent type. Used bytes: {total_bytes} | Unused bits: {unused_bits}");
|
format!("Fieldset that facilitates compacting the parent type. Used bytes: {total_bytes} | Unused bits: {unused_bits}");
|
||||||
let bitflag_encoded_bytes = format!("Used bytes by [`{flags_ident}`]");
|
let bitflag_encoded_bytes = format!("Used bytes by [`{flags_ident}`]");
|
||||||
|
let impl_bitflag_encoded_bytes = if has_lifetime {
|
||||||
|
quote! {
|
||||||
|
impl<'a> #ident<'a> {
|
||||||
|
#[doc = #bitflag_encoded_bytes]
|
||||||
|
pub const fn bitflag_encoded_bytes() -> usize {
|
||||||
|
#total_bytes as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
impl #ident {
|
||||||
|
#[doc = #bitflag_encoded_bytes]
|
||||||
|
pub const fn bitflag_encoded_bytes() -> usize {
|
||||||
|
#total_bytes as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Generate the flag struct.
|
// Generate the flag struct.
|
||||||
quote! {
|
quote! {
|
||||||
impl #ident {
|
#impl_bitflag_encoded_bytes
|
||||||
#[doc = #bitflag_encoded_bytes]
|
|
||||||
pub const fn bitflag_encoded_bytes() -> usize {
|
|
||||||
#total_bytes as usize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub use #mod_flags_ident::#flags_ident;
|
pub use #mod_flags_ident::#flags_ident;
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
mod #mod_flags_ident {
|
mod #mod_flags_ident {
|
||||||
|
|||||||
@ -4,7 +4,12 @@ use super::*;
|
|||||||
use convert_case::{Case, Casing};
|
use convert_case::{Case, Casing};
|
||||||
|
|
||||||
/// Generates code to implement the `Compact` trait for a data type.
|
/// Generates code to implement the `Compact` trait for a data type.
|
||||||
pub fn generate_from_to(ident: &Ident, fields: &FieldList, is_zstd: bool) -> TokenStream2 {
|
pub fn generate_from_to(
|
||||||
|
ident: &Ident,
|
||||||
|
has_lifetime: bool,
|
||||||
|
fields: &FieldList,
|
||||||
|
is_zstd: bool,
|
||||||
|
) -> TokenStream2 {
|
||||||
let flags = format_ident!("{ident}Flags");
|
let flags = format_ident!("{ident}Flags");
|
||||||
|
|
||||||
let to_compact = generate_to_compact(fields, ident, is_zstd);
|
let to_compact = generate_to_compact(fields, ident, is_zstd);
|
||||||
@ -15,26 +20,58 @@ pub fn generate_from_to(ident: &Ident, fields: &FieldList, is_zstd: bool) -> Tok
|
|||||||
let fuzz = format_ident!("fuzz_test_{snake_case_ident}");
|
let fuzz = format_ident!("fuzz_test_{snake_case_ident}");
|
||||||
let test = format_ident!("fuzz_{snake_case_ident}");
|
let test = format_ident!("fuzz_{snake_case_ident}");
|
||||||
|
|
||||||
|
let lifetime = if has_lifetime {
|
||||||
|
quote! { 'a }
|
||||||
|
} else {
|
||||||
|
quote! {}
|
||||||
|
};
|
||||||
|
|
||||||
|
let impl_compact = if has_lifetime {
|
||||||
|
quote! {
|
||||||
|
impl<#lifetime> Compact for #ident<#lifetime>
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
impl Compact for #ident
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let fn_from_compact = if has_lifetime {
|
||||||
|
quote! { unimplemented!("from_compact not supported with ref structs") }
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
let (flags, mut buf) = #flags::from(buf);
|
||||||
|
#from_compact
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let fuzz_tests = if has_lifetime {
|
||||||
|
quote! {}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
#[cfg(test)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[test_fuzz::test_fuzz]
|
||||||
|
fn #fuzz(obj: #ident) {
|
||||||
|
let mut buf = vec![];
|
||||||
|
let len = obj.clone().to_compact(&mut buf);
|
||||||
|
let (same_obj, buf) = #ident::from_compact(buf.as_ref(), len);
|
||||||
|
assert_eq!(obj, same_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn #test() {
|
||||||
|
#fuzz(#ident::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Build function
|
// Build function
|
||||||
quote! {
|
quote! {
|
||||||
|
#fuzz_tests
|
||||||
|
|
||||||
#[cfg(test)]
|
#impl_compact {
|
||||||
#[allow(dead_code)]
|
fn to_compact<B>(&self, buf: &mut B) -> usize where B: bytes::BufMut + AsMut<[u8]> {
|
||||||
#[test_fuzz::test_fuzz]
|
|
||||||
fn #fuzz(obj: #ident) {
|
|
||||||
let mut buf = vec![];
|
|
||||||
let len = obj.clone().to_compact(&mut buf);
|
|
||||||
let (same_obj, buf) = #ident::from_compact(buf.as_ref(), len);
|
|
||||||
assert_eq!(obj, same_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
pub fn #test() {
|
|
||||||
#fuzz(#ident::default())
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Compact for #ident {
|
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize where B: bytes::BufMut + AsMut<[u8]> {
|
|
||||||
let mut flags = #flags::default();
|
let mut flags = #flags::default();
|
||||||
let mut total_length = 0;
|
let mut total_length = 0;
|
||||||
#(#to_compact)*
|
#(#to_compact)*
|
||||||
@ -42,8 +79,7 @@ pub fn generate_from_to(ident: &Ident, fields: &FieldList, is_zstd: bool) -> Tok
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn from_compact(mut buf: &[u8], len: usize) -> (Self, &[u8]) {
|
fn from_compact(mut buf: &[u8], len: usize) -> (Self, &[u8]) {
|
||||||
let (flags, mut buf) = #flags::from(buf);
|
#fn_from_compact
|
||||||
#from_compact
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use proc_macro2::{Ident, TokenStream as TokenStream2};
|
use proc_macro2::{Ident, TokenStream as TokenStream2};
|
||||||
use quote::{format_ident, quote};
|
use quote::{format_ident, quote};
|
||||||
use syn::{parse_macro_input, Data, DeriveInput};
|
use syn::{parse_macro_input, Data, DeriveInput, Generics};
|
||||||
|
|
||||||
mod generator;
|
mod generator;
|
||||||
use generator::*;
|
use generator::*;
|
||||||
@ -43,13 +43,20 @@ pub enum FieldTypes {
|
|||||||
pub fn derive(input: TokenStream, is_zstd: bool) -> TokenStream {
|
pub fn derive(input: TokenStream, is_zstd: bool) -> TokenStream {
|
||||||
let mut output = quote! {};
|
let mut output = quote! {};
|
||||||
|
|
||||||
let DeriveInput { ident, data, .. } = parse_macro_input!(input);
|
let DeriveInput { ident, data, generics, .. } = parse_macro_input!(input);
|
||||||
|
|
||||||
|
let has_lifetime = has_lifetime(&generics);
|
||||||
|
|
||||||
let fields = get_fields(&data);
|
let fields = get_fields(&data);
|
||||||
output.extend(generate_flag_struct(&ident, &fields, is_zstd));
|
output.extend(generate_flag_struct(&ident, has_lifetime, &fields, is_zstd));
|
||||||
output.extend(generate_from_to(&ident, &fields, is_zstd));
|
output.extend(generate_from_to(&ident, has_lifetime, &fields, is_zstd));
|
||||||
output.into()
|
output.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_lifetime(generics: &Generics) -> bool {
|
||||||
|
generics.lifetimes().next().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
/// Given a list of fields on a struct, extract their fields and types.
|
/// Given a list of fields on a struct, extract their fields and types.
|
||||||
pub fn get_fields(data: &Data) -> FieldList {
|
pub fn get_fields(data: &Data) -> FieldList {
|
||||||
let mut fields = vec![];
|
let mut fields = vec![];
|
||||||
@ -60,7 +67,7 @@ pub fn get_fields(data: &Data) -> FieldList {
|
|||||||
for field in &data_fields.named {
|
for field in &data_fields.named {
|
||||||
load_field(field, &mut fields, false);
|
load_field(field, &mut fields, false);
|
||||||
}
|
}
|
||||||
assert_eq!(fields.len(), data_fields.named.len());
|
assert_eq!(fields.len(), data_fields.named.len(), "get_fields");
|
||||||
}
|
}
|
||||||
syn::Fields::Unnamed(ref data_fields) => {
|
syn::Fields::Unnamed(ref data_fields) => {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -99,37 +106,54 @@ pub fn get_fields(data: &Data) -> FieldList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn load_field(field: &syn::Field, fields: &mut FieldList, is_enum: bool) {
|
fn load_field(field: &syn::Field, fields: &mut FieldList, is_enum: bool) {
|
||||||
if let syn::Type::Path(ref path) = field.ty {
|
match field.ty {
|
||||||
let segments = &path.path.segments;
|
syn::Type::Reference(ref reference) => match &*reference.elem {
|
||||||
if !segments.is_empty() {
|
syn::Type::Path(path) => {
|
||||||
let mut ftype = String::new();
|
load_field_from_segments(&path.path.segments, is_enum, fields, field)
|
||||||
|
}
|
||||||
|
_ => unimplemented!("{:?}", &field.ident),
|
||||||
|
},
|
||||||
|
syn::Type::Path(ref path) => {
|
||||||
|
load_field_from_segments(&path.path.segments, is_enum, fields, field)
|
||||||
|
}
|
||||||
|
_ => unimplemented!("{:?}", &field.ident),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut use_alt_impl: UseAlternative = false;
|
fn load_field_from_segments(
|
||||||
|
segments: &syn::punctuated::Punctuated<syn::PathSegment, syn::token::PathSep>,
|
||||||
|
is_enum: bool,
|
||||||
|
fields: &mut Vec<FieldTypes>,
|
||||||
|
field: &syn::Field,
|
||||||
|
) {
|
||||||
|
if !segments.is_empty() {
|
||||||
|
let mut ftype = String::new();
|
||||||
|
|
||||||
for (index, segment) in segments.iter().enumerate() {
|
let mut use_alt_impl: UseAlternative = false;
|
||||||
ftype.push_str(&segment.ident.to_string());
|
|
||||||
if index < segments.len() - 1 {
|
|
||||||
ftype.push_str("::");
|
|
||||||
}
|
|
||||||
|
|
||||||
use_alt_impl = should_use_alt_impl(&ftype, segment);
|
for (index, segment) in segments.iter().enumerate() {
|
||||||
|
ftype.push_str(&segment.ident.to_string());
|
||||||
|
if index < segments.len() - 1 {
|
||||||
|
ftype.push_str("::");
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_enum {
|
use_alt_impl = should_use_alt_impl(&ftype, segment);
|
||||||
fields.push(FieldTypes::EnumUnnamedField((ftype.to_string(), use_alt_impl)));
|
}
|
||||||
} else {
|
|
||||||
let should_compact = is_flag_type(&ftype) ||
|
|
||||||
field.attrs.iter().any(|attr| {
|
|
||||||
attr.path().segments.iter().any(|path| path.ident == "maybe_zero")
|
|
||||||
});
|
|
||||||
|
|
||||||
fields.push(FieldTypes::StructField((
|
if is_enum {
|
||||||
field.ident.as_ref().map(|i| i.to_string()).unwrap_or_default(),
|
fields.push(FieldTypes::EnumUnnamedField((ftype.to_string(), use_alt_impl)));
|
||||||
ftype,
|
} else {
|
||||||
should_compact,
|
let should_compact = is_flag_type(&ftype) ||
|
||||||
use_alt_impl,
|
field.attrs.iter().any(|attr| {
|
||||||
)));
|
attr.path().segments.iter().any(|path| path.ident == "maybe_zero")
|
||||||
}
|
});
|
||||||
|
|
||||||
|
fields.push(FieldTypes::StructField((
|
||||||
|
field.ident.as_ref().map(|i| i.to_string()).unwrap_or_default(),
|
||||||
|
ftype,
|
||||||
|
should_compact,
|
||||||
|
use_alt_impl,
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,8 +235,8 @@ mod tests {
|
|||||||
let mut output = quote! {};
|
let mut output = quote! {};
|
||||||
let DeriveInput { ident, data, .. } = parse2(f_struct).unwrap();
|
let DeriveInput { ident, data, .. } = parse2(f_struct).unwrap();
|
||||||
let fields = get_fields(&data);
|
let fields = get_fields(&data);
|
||||||
output.extend(generate_flag_struct(&ident, &fields, false));
|
output.extend(generate_flag_struct(&ident, false, &fields, false));
|
||||||
output.extend(generate_from_to(&ident, &fields, false));
|
output.extend(generate_from_to(&ident, false, &fields, false));
|
||||||
|
|
||||||
// Expected output in a TokenStream format. Commas matter!
|
// Expected output in a TokenStream format. Commas matter!
|
||||||
let should_output = quote! {
|
let should_output = quote! {
|
||||||
@ -267,7 +291,7 @@ mod tests {
|
|||||||
fuzz_test_test_struct(TestStruct::default())
|
fuzz_test_test_struct(TestStruct::default())
|
||||||
}
|
}
|
||||||
impl Compact for TestStruct {
|
impl Compact for TestStruct {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize where B: bytes::BufMut + AsMut<[u8]> {
|
fn to_compact<B>(&self, buf: &mut B) -> usize where B: bytes::BufMut + AsMut<[u8]> {
|
||||||
let mut flags = TestStructFlags::default();
|
let mut flags = TestStructFlags::default();
|
||||||
let mut total_length = 0;
|
let mut total_length = 0;
|
||||||
let mut buffer = bytes::BytesMut::new();
|
let mut buffer = bytes::BytesMut::new();
|
||||||
|
|||||||
@ -42,7 +42,8 @@ pub fn reth_codec(args: TokenStream, input: TokenStream) -> TokenStream {
|
|||||||
let ast = parse_macro_input!(input as DeriveInput);
|
let ast = parse_macro_input!(input as DeriveInput);
|
||||||
|
|
||||||
let with_zstd = args.clone().into_iter().any(|tk| tk.to_string() == "zstd");
|
let with_zstd = args.clone().into_iter().any(|tk| tk.to_string() == "zstd");
|
||||||
|
let without_arbitrary = args.clone().into_iter().any(|tk| tk.to_string() == "no_arbitrary");
|
||||||
|
|
||||||
let compact = if with_zstd {
|
let compact = if with_zstd {
|
||||||
quote! {
|
quote! {
|
||||||
#[derive(CompactZstd)]
|
#[derive(CompactZstd)]
|
||||||
@ -57,10 +58,8 @@ pub fn reth_codec(args: TokenStream, input: TokenStream) -> TokenStream {
|
|||||||
.into()
|
.into()
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(first_arg) = args.clone().into_iter().next() {
|
if without_arbitrary {
|
||||||
if first_arg.to_string() == "no_arbitrary" {
|
return compact
|
||||||
return compact
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut args = args.into_iter().collect::<Vec<_>>();
|
let mut args = args.into_iter().collect::<Vec<_>>();
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use alloy_primitives::Address;
|
|||||||
|
|
||||||
/// Implement `Compact` for `AccessListItem` and `AccessList`.
|
/// Implement `Compact` for `AccessListItem` and `AccessList`.
|
||||||
impl Compact for AccessListItem {
|
impl Compact for AccessListItem {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -26,7 +26,7 @@ impl Compact for AccessListItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for AccessList {
|
impl Compact for AccessList {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -56,7 +56,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_roundtrip_compact_access_list_item(access_list_item in arb::<AccessListItem>()) {
|
fn test_roundtrip_compact_access_list_item(access_list_item in arb::<AccessListItem>()) {
|
||||||
let mut compacted_access_list_item = Vec::<u8>::new();
|
let mut compacted_access_list_item = Vec::<u8>::new();
|
||||||
let len = access_list_item.clone().to_compact(&mut compacted_access_list_item);
|
let len = access_list_item.to_compact(&mut compacted_access_list_item);
|
||||||
|
|
||||||
let (decoded_access_list_item, _) = AccessListItem::from_compact(&compacted_access_list_item, len);
|
let (decoded_access_list_item, _) = AccessListItem::from_compact(&compacted_access_list_item, len);
|
||||||
assert_eq!(access_list_item, decoded_access_list_item);
|
assert_eq!(access_list_item, decoded_access_list_item);
|
||||||
@ -67,7 +67,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_roundtrip_compact_access_list(access_list in arb::<AccessList>()) {
|
fn test_roundtrip_compact_access_list(access_list in arb::<AccessList>()) {
|
||||||
let mut compacted_access_list = Vec::<u8>::new();
|
let mut compacted_access_list = Vec::<u8>::new();
|
||||||
let len = access_list.clone().to_compact(&mut compacted_access_list);
|
let len = access_list.to_compact(&mut compacted_access_list);
|
||||||
|
|
||||||
let (decoded_access_list, _) = AccessList::from_compact(&compacted_access_list, len);
|
let (decoded_access_list, _) = AccessList::from_compact(&compacted_access_list, len);
|
||||||
assert_eq!(access_list, decoded_access_list);
|
assert_eq!(access_list, decoded_access_list);
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use core::ops::Deref;
|
||||||
|
|
||||||
use crate::Compact;
|
use crate::Compact;
|
||||||
use alloy_eips::eip7702::{Authorization as AlloyAuthorization, SignedAuthorization};
|
use alloy_eips::eip7702::{Authorization as AlloyAuthorization, SignedAuthorization};
|
||||||
use alloy_primitives::{Address, ChainId, U256};
|
use alloy_primitives::{Address, ChainId, U256};
|
||||||
@ -17,7 +19,7 @@ struct Authorization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for AlloyAuthorization {
|
impl Compact for AlloyAuthorization {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -38,11 +40,11 @@ impl Compact for AlloyAuthorization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for SignedAuthorization {
|
impl Compact for SignedAuthorization {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
let (auth, signature) = self.into_parts();
|
let signature = self.signature();
|
||||||
let (v, r, s) = (signature.v(), signature.r(), signature.s());
|
let (v, r, s) = (signature.v(), signature.r(), signature.s());
|
||||||
buf.put_u8(v.y_parity_byte());
|
buf.put_u8(v.y_parity_byte());
|
||||||
buf.put_slice(r.as_le_slice());
|
buf.put_slice(r.as_le_slice());
|
||||||
@ -50,7 +52,7 @@ impl Compact for SignedAuthorization {
|
|||||||
|
|
||||||
// to_compact doesn't write the len to buffer.
|
// to_compact doesn't write the len to buffer.
|
||||||
// By placing it as last, we don't need to store it either.
|
// By placing it as last, we don't need to store it either.
|
||||||
1 + 32 + 32 + auth.to_compact(buf)
|
1 + 32 + 32 + self.deref().to_compact(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_compact(mut buf: &[u8], len: usize) -> (Self, &[u8]) {
|
fn from_compact(mut buf: &[u8], len: usize) -> (Self, &[u8]) {
|
||||||
@ -89,7 +91,7 @@ mod tests {
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
let mut compacted_authorization = Vec::<u8>::new();
|
let mut compacted_authorization = Vec::<u8>::new();
|
||||||
let len = authorization.clone().to_compact(&mut compacted_authorization);
|
let len = authorization.to_compact(&mut compacted_authorization);
|
||||||
let (decoded_authorization, _) =
|
let (decoded_authorization, _) =
|
||||||
SignedAuthorization::from_compact(&compacted_authorization, len);
|
SignedAuthorization::from_compact(&compacted_authorization, len);
|
||||||
assert_eq!(authorization, decoded_authorization);
|
assert_eq!(authorization, decoded_authorization);
|
||||||
|
|||||||
@ -7,6 +7,21 @@ use serde::{Deserialize, Serialize};
|
|||||||
/// GenesisAccount acts as bridge which simplifies Compact implementation for AlloyGenesisAccount.
|
/// GenesisAccount acts as bridge which simplifies Compact implementation for AlloyGenesisAccount.
|
||||||
///
|
///
|
||||||
/// Notice: Make sure this struct is 1:1 with `alloy_genesis::GenesisAccount`
|
/// Notice: Make sure this struct is 1:1 with `alloy_genesis::GenesisAccount`
|
||||||
|
#[reth_codec(no_arbitrary)]
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
struct GenesisAccountRef<'a> {
|
||||||
|
/// The nonce of the account at genesis.
|
||||||
|
nonce: Option<u64>,
|
||||||
|
/// The balance of the account at genesis.
|
||||||
|
balance: &'a U256,
|
||||||
|
/// The account's bytecode at genesis.
|
||||||
|
code: Option<&'a Bytes>,
|
||||||
|
/// The account's storage at genesis.
|
||||||
|
storage: Option<StorageEntries>,
|
||||||
|
/// The account's private key. Should only be used for testing.
|
||||||
|
private_key: Option<&'a B256>,
|
||||||
|
}
|
||||||
|
|
||||||
#[reth_codec]
|
#[reth_codec]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
|
||||||
struct GenesisAccount {
|
struct GenesisAccount {
|
||||||
@ -36,18 +51,21 @@ struct StorageEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for AlloyGenesisAccount {
|
impl Compact for AlloyGenesisAccount {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
let account = GenesisAccount {
|
let account = GenesisAccountRef {
|
||||||
nonce: self.nonce,
|
nonce: self.nonce,
|
||||||
balance: self.balance,
|
balance: &self.balance,
|
||||||
code: self.code,
|
code: self.code.as_ref(),
|
||||||
storage: self.storage.map(|s| StorageEntries {
|
storage: self.storage.as_ref().map(|s| StorageEntries {
|
||||||
entries: s.into_iter().map(|(key, value)| StorageEntry { key, value }).collect(),
|
entries: s
|
||||||
|
.iter()
|
||||||
|
.map(|(key, value)| StorageEntry { key: *key, value: *value })
|
||||||
|
.collect(),
|
||||||
}),
|
}),
|
||||||
private_key: self.private_key,
|
private_key: self.private_key.as_ref(),
|
||||||
};
|
};
|
||||||
account.to_compact(buf)
|
account.to_compact(buf)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,14 +6,14 @@ use bytes::BufMut;
|
|||||||
|
|
||||||
/// Implement `Compact` for `LogData` and `Log`.
|
/// Implement `Compact` for `LogData` and `Log`.
|
||||||
impl Compact for LogData {
|
impl Compact for LogData {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: BufMut + AsMut<[u8]>,
|
B: BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
let (topics, data) = self.split();
|
|
||||||
topics.specialized_to_compact(&mut buffer);
|
self.topics().specialized_to_compact(&mut buffer);
|
||||||
data.to_compact(&mut buffer);
|
self.data.to_compact(&mut buffer);
|
||||||
buf.put(&buffer[..]);
|
buf.put(&buffer[..]);
|
||||||
buffer.len()
|
buffer.len()
|
||||||
}
|
}
|
||||||
@ -28,7 +28,7 @@ impl Compact for LogData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for Log {
|
impl Compact for Log {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: BufMut + AsMut<[u8]>,
|
B: BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -60,7 +60,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn roundtrip(log: Log) {
|
fn roundtrip(log: Log) {
|
||||||
let mut buf = Vec::<u8>::new();
|
let mut buf = Vec::<u8>::new();
|
||||||
let len = log.clone().to_compact(&mut buf);
|
let len = log.to_compact(&mut buf);
|
||||||
let (decoded, _) = Log::from_compact(&buf, len);
|
let (decoded, _) = Log::from_compact(&buf, len);
|
||||||
assert_eq!(log, decoded);
|
assert_eq!(log, decoded);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use alloy_primitives::Bytes;
|
|||||||
use bytes::BufMut;
|
use bytes::BufMut;
|
||||||
|
|
||||||
impl Compact for Request {
|
impl Compact for Request {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: BufMut + AsMut<[u8]>,
|
B: BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use alloy_trie::{hash_builder::HashBuilderValue, BranchNodeCompact, TrieMask};
|
|||||||
use bytes::{Buf, BufMut};
|
use bytes::{Buf, BufMut};
|
||||||
|
|
||||||
impl Compact for HashBuilderValue {
|
impl Compact for HashBuilderValue {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: BufMut + AsMut<[u8]>,
|
B: BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -42,7 +42,7 @@ impl Compact for HashBuilderValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for BranchNodeCompact {
|
impl Compact for BranchNodeCompact {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -99,7 +99,7 @@ impl Compact for BranchNodeCompact {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for TrieMask {
|
impl Compact for TrieMask {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -132,7 +132,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
let compact_len = n.clone().to_compact(&mut out);
|
let compact_len = n.to_compact(&mut out);
|
||||||
assert_eq!(BranchNodeCompact::from_compact(&out, compact_len).0, n);
|
assert_eq!(BranchNodeCompact::from_compact(&out, compact_len).0, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use crate::Compact;
|
|||||||
use alloy_primitives::{Address, TxKind};
|
use alloy_primitives::{Address, TxKind};
|
||||||
|
|
||||||
impl Compact for TxKind {
|
impl Compact for TxKind {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
|
|||||||
@ -21,7 +21,7 @@ struct Withdrawal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for AlloyWithdrawal {
|
impl Compact for AlloyWithdrawal {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
pub use reth_codecs_derive::*;
|
pub use reth_codecs_derive::*;
|
||||||
|
|
||||||
use alloy_primitives::{Address, Bloom, Bytes, FixedBytes, U256};
|
use alloy_primitives::{Address, Bloom, Bytes, FixedBytes, U256};
|
||||||
use bytes::Buf;
|
use bytes::{Buf, BufMut};
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
@ -49,7 +49,7 @@ mod alloy;
|
|||||||
/// size array like `Vec<B256>`.
|
/// size array like `Vec<B256>`.
|
||||||
pub trait Compact: Sized {
|
pub trait Compact: Sized {
|
||||||
/// Takes a buffer which can be written to. *Ideally*, it returns the length written to.
|
/// Takes a buffer which can be written to. *Ideally*, it returns the length written to.
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>;
|
B: bytes::BufMut + AsMut<[u8]>;
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ pub trait Compact: Sized {
|
|||||||
|
|
||||||
/// "Optional": If there's no good reason to use it, don't.
|
/// "Optional": If there's no good reason to use it, don't.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn specialized_to_compact<B>(self, buf: &mut B) -> usize
|
fn specialized_to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -77,12 +77,25 @@ pub trait Compact: Sized {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Compact> Compact for &T {
|
||||||
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
|
where
|
||||||
|
B: BufMut + AsMut<[u8]>,
|
||||||
|
{
|
||||||
|
(*self).to_compact(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_compact(_: &[u8], _: usize) -> (Self, &[u8]) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// To be used with `Option<CompactPlaceholder>` to place or replace one bit on the bitflag struct.
|
/// To be used with `Option<CompactPlaceholder>` to place or replace one bit on the bitflag struct.
|
||||||
pub type CompactPlaceholder = ();
|
pub type CompactPlaceholder = ();
|
||||||
|
|
||||||
impl Compact for CompactPlaceholder {
|
impl Compact for CompactPlaceholder {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_compact<B>(self, _: &mut B) -> usize
|
fn to_compact<B>(&self, _: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -100,7 +113,7 @@ macro_rules! impl_uint_compact {
|
|||||||
$(
|
$(
|
||||||
impl Compact for $name {
|
impl Compact for $name {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where B: bytes::BufMut + AsMut<[u8]>
|
where B: bytes::BufMut + AsMut<[u8]>
|
||||||
{
|
{
|
||||||
let leading = self.leading_zeros() as usize / 8;
|
let leading = self.leading_zeros() as usize / 8;
|
||||||
@ -132,7 +145,7 @@ where
|
|||||||
{
|
{
|
||||||
/// Returns 0 since we won't include it in the `StructFlags`.
|
/// Returns 0 since we won't include it in the `StructFlags`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -172,7 +185,7 @@ where
|
|||||||
|
|
||||||
/// To be used by fixed sized types like `Vec<B256>`.
|
/// To be used by fixed sized types like `Vec<B256>`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn specialized_to_compact<B>(self, buf: &mut B) -> usize
|
fn specialized_to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -199,13 +212,64 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Compact for &[T]
|
||||||
|
where
|
||||||
|
T: Compact,
|
||||||
|
{
|
||||||
|
/// Returns 0 since we won't include it in the `StructFlags`.
|
||||||
|
#[inline]
|
||||||
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
|
where
|
||||||
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
|
{
|
||||||
|
encode_varuint(self.len(), buf);
|
||||||
|
|
||||||
|
let mut tmp: Vec<u8> = Vec::with_capacity(64);
|
||||||
|
|
||||||
|
for element in *self {
|
||||||
|
tmp.clear();
|
||||||
|
|
||||||
|
// We don't know the length until we compact it
|
||||||
|
let length = element.to_compact(&mut tmp);
|
||||||
|
encode_varuint(length, buf);
|
||||||
|
|
||||||
|
buf.put_slice(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_compact(_: &[u8], _: usize) -> (Self, &[u8]) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// To be used by fixed sized types like `&[B256]`.
|
||||||
|
#[inline]
|
||||||
|
fn specialized_to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
|
where
|
||||||
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
|
{
|
||||||
|
encode_varuint(self.len(), buf);
|
||||||
|
for element in *self {
|
||||||
|
element.to_compact(buf);
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn specialized_from_compact(_: &[u8], _: usize) -> (Self, &[u8]) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Compact for Option<T>
|
impl<T> Compact for Option<T>
|
||||||
where
|
where
|
||||||
T: Compact,
|
T: Compact,
|
||||||
{
|
{
|
||||||
/// Returns 0 for `None` and 1 for `Some(_)`.
|
/// Returns 0 for `None` and 1 for `Some(_)`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -238,7 +302,7 @@ where
|
|||||||
|
|
||||||
/// To be used by fixed sized types like `Option<B256>`.
|
/// To be used by fixed sized types like `Option<B256>`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn specialized_to_compact<B>(self, buf: &mut B) -> usize
|
fn specialized_to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -264,7 +328,7 @@ where
|
|||||||
|
|
||||||
impl Compact for U256 {
|
impl Compact for U256 {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -289,12 +353,12 @@ impl Compact for U256 {
|
|||||||
|
|
||||||
impl Compact for Bytes {
|
impl Compact for Bytes {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
let len = self.len();
|
let len = self.len();
|
||||||
buf.put(self.0);
|
buf.put_slice(&self.0);
|
||||||
len
|
len
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,11 +370,11 @@ impl Compact for Bytes {
|
|||||||
|
|
||||||
impl<const N: usize> Compact for [u8; N] {
|
impl<const N: usize> Compact for [u8; N] {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
buf.put_slice(&self);
|
buf.put_slice(&self[..]);
|
||||||
N
|
N
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,7 +397,7 @@ macro_rules! impl_compact_for_wrapped_bytes {
|
|||||||
$(
|
$(
|
||||||
impl Compact for $name {
|
impl Compact for $name {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>
|
B: bytes::BufMut + AsMut<[u8]>
|
||||||
{
|
{
|
||||||
@ -353,7 +417,7 @@ impl_compact_for_wrapped_bytes!(Address, Bloom);
|
|||||||
|
|
||||||
impl<const N: usize> Compact for FixedBytes<N> {
|
impl<const N: usize> Compact for FixedBytes<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -370,11 +434,11 @@ impl<const N: usize> Compact for FixedBytes<N> {
|
|||||||
impl Compact for bool {
|
impl Compact for bool {
|
||||||
/// `bool` vars go directly to the `StructFlags` and are not written to the buffer.
|
/// `bool` vars go directly to the `StructFlags` and are not written to the buffer.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_compact<B>(self, _: &mut B) -> usize
|
fn to_compact<B>(&self, _: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
self as usize
|
*self as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `bool` expects the real value to come in `len`, and does not advance the cursor.
|
/// `bool` expects the real value to come in `len`, and does not advance the cursor.
|
||||||
@ -426,7 +490,7 @@ mod tests {
|
|||||||
let arr = [1, 2, 3, 4, 5];
|
let arr = [1, 2, 3, 4, 5];
|
||||||
let list = Bytes::copy_from_slice(&arr);
|
let list = Bytes::copy_from_slice(&arr);
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
assert_eq!(list.clone().to_compact(&mut buf), list.len());
|
assert_eq!(list.to_compact(&mut buf), list.len());
|
||||||
|
|
||||||
// Add some noise data.
|
// Add some noise data.
|
||||||
buf.push(1);
|
buf.push(1);
|
||||||
@ -506,7 +570,7 @@ mod tests {
|
|||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
|
|
||||||
// Vec doesn't return a total length
|
// Vec doesn't return a total length
|
||||||
assert_eq!(list.clone().to_compact(&mut buf), 0);
|
assert_eq!(list.to_compact(&mut buf), 0);
|
||||||
|
|
||||||
// Add some noise data in the end that should be returned by `from_compact`.
|
// Add some noise data in the end that should be returned by `from_compact`.
|
||||||
buf.extend([1u8, 2]);
|
buf.extend([1u8, 2]);
|
||||||
@ -561,6 +625,33 @@ mod tests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn compact_slice() {
|
||||||
|
let vec_list = vec![B256::ZERO, B256::random(), B256::random(), B256::ZERO];
|
||||||
|
|
||||||
|
// to_compact
|
||||||
|
{
|
||||||
|
let mut vec_buf = vec![];
|
||||||
|
assert_eq!(vec_list.to_compact(&mut vec_buf), 0);
|
||||||
|
|
||||||
|
let mut slice_buf = vec![];
|
||||||
|
assert_eq!(vec_list.as_slice().to_compact(&mut slice_buf), 0);
|
||||||
|
|
||||||
|
assert_eq!(vec_buf, slice_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// specialized_to_compact
|
||||||
|
{
|
||||||
|
let mut vec_buf = vec![];
|
||||||
|
assert_eq!(vec_list.specialized_to_compact(&mut vec_buf), 0);
|
||||||
|
|
||||||
|
let mut slice_buf = vec![];
|
||||||
|
assert_eq!(vec_list.as_slice().specialized_to_compact(&mut slice_buf), 0);
|
||||||
|
|
||||||
|
assert_eq!(vec_buf, slice_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[reth_codec]
|
#[reth_codec]
|
||||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
struct TestStruct {
|
struct TestStruct {
|
||||||
@ -627,15 +718,15 @@ mod tests {
|
|||||||
#[test_fuzz::test_fuzz]
|
#[test_fuzz::test_fuzz]
|
||||||
fn compact_test_enum_all_variants(var0: TestEnum, var1: TestEnum, var2: TestEnum) {
|
fn compact_test_enum_all_variants(var0: TestEnum, var1: TestEnum, var2: TestEnum) {
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
var0.clone().to_compact(&mut buf);
|
var0.to_compact(&mut buf);
|
||||||
assert_eq!(TestEnum::from_compact(&buf, buf.len()).0, var0);
|
assert_eq!(TestEnum::from_compact(&buf, buf.len()).0, var0);
|
||||||
|
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
var1.clone().to_compact(&mut buf);
|
var1.to_compact(&mut buf);
|
||||||
assert_eq!(TestEnum::from_compact(&buf, buf.len()).0, var1);
|
assert_eq!(TestEnum::from_compact(&buf, buf.len()).0, var1);
|
||||||
|
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
var2.clone().to_compact(&mut buf);
|
var2.to_compact(&mut buf);
|
||||||
assert_eq!(TestEnum::from_compact(&buf, buf.len()).0, var2);
|
assert_eq!(TestEnum::from_compact(&buf, buf.len()).0, var2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ pub struct AccountBeforeTx {
|
|||||||
// and compress second part of the value. If we have compression
|
// and compress second part of the value. If we have compression
|
||||||
// over whole value (Even SubKey) that would mess up fetching of values with seek_by_key_subkey
|
// over whole value (Even SubKey) that would mess up fetching of values with seek_by_key_subkey
|
||||||
impl Compact for AccountBeforeTx {
|
impl Compact for AccountBeforeTx {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
|
|||||||
@ -23,14 +23,13 @@ impl ClientVersion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for ClientVersion {
|
impl Compact for ClientVersion {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
let Self { version, git_sha, build_timestamp } = self;
|
self.version.as_bytes().to_compact(buf);
|
||||||
version.into_bytes().to_compact(buf);
|
self.git_sha.as_bytes().to_compact(buf);
|
||||||
git_sha.into_bytes().to_compact(buf);
|
self.build_timestamp.as_bytes().to_compact(buf)
|
||||||
build_timestamp.into_bytes().to_compact(buf)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) {
|
fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) {
|
||||||
|
|||||||
@ -185,7 +185,7 @@ macro_rules! impl_compression_for_compact {
|
|||||||
type Compressed = Vec<u8>;
|
type Compressed = Vec<u8>;
|
||||||
|
|
||||||
fn compress_to_buf<B: bytes::BufMut + AsMut<[u8]>>(self, buf: &mut B) {
|
fn compress_to_buf<B: bytes::BufMut + AsMut<[u8]>>(self, buf: &mut B) {
|
||||||
let _ = Compact::to_compact(self, buf);
|
let _ = Compact::to_compact(&self, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +235,7 @@ macro_rules! impl_compression_fixed_compact {
|
|||||||
type Compressed = Vec<u8>;
|
type Compressed = Vec<u8>;
|
||||||
|
|
||||||
fn compress_to_buf<B: bytes::BufMut + AsMut<[u8]>>(self, buf: &mut B) {
|
fn compress_to_buf<B: bytes::BufMut + AsMut<[u8]>>(self, buf: &mut B) {
|
||||||
let _ = Compact::to_compact(self, buf);
|
let _ = Compact::to_compact(&self, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn uncompressable_ref(&self) -> Option<&[u8]> {
|
fn uncompressable_ref(&self) -> Option<&[u8]> {
|
||||||
|
|||||||
@ -60,7 +60,7 @@ impl From<HashBuilder> for HashBuilderState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for HashBuilderState {
|
impl Compact for HashBuilderState {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -163,7 +163,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn hash_builder_state_roundtrip(state in arb::<HashBuilderState>()) {
|
fn hash_builder_state_roundtrip(state in arb::<HashBuilderState>()) {
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
let len = state.clone().to_compact(&mut buf);
|
let len = state.to_compact(&mut buf);
|
||||||
let (decoded, _) = HashBuilderState::from_compact(&buf, len);
|
let (decoded, _) = HashBuilderState::from_compact(&buf, len);
|
||||||
assert_eq!(state, decoded);
|
assert_eq!(state, decoded);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,7 +57,7 @@ impl core::borrow::Borrow<[u8]> for StoredNibbles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for StoredNibbles {
|
impl Compact for StoredNibbles {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -98,7 +98,7 @@ impl From<StoredNibblesSubKey> for Nibbles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for StoredNibblesSubKey {
|
impl Compact for StoredNibblesSubKey {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
|
|||||||
@ -15,7 +15,7 @@ pub struct StorageTrieEntry {
|
|||||||
// and compress second part of the value. If we have compression
|
// and compress second part of the value. If we have compression
|
||||||
// over whole value (Even SubKey) that would mess up fetching of values with seek_by_key_subkey
|
// over whole value (Even SubKey) that would mess up fetching of values with seek_by_key_subkey
|
||||||
impl Compact for StorageTrieEntry {
|
impl Compact for StorageTrieEntry {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
|
|||||||
@ -14,7 +14,7 @@ pub struct StoredSubNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Compact for StoredSubNode {
|
impl Compact for StoredSubNode {
|
||||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
||||||
where
|
where
|
||||||
B: bytes::BufMut + AsMut<[u8]>,
|
B: bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
@ -33,7 +33,7 @@ impl Compact for StoredSubNode {
|
|||||||
len += 1;
|
len += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(node) = self.node {
|
if let Some(node) = &self.node {
|
||||||
buf.put_u8(1);
|
buf.put_u8(1);
|
||||||
len += 1;
|
len += 1;
|
||||||
len += node.to_compact(buf);
|
len += node.to_compact(buf);
|
||||||
@ -87,7 +87,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut encoded = vec![];
|
let mut encoded = vec![];
|
||||||
subnode.clone().to_compact(&mut encoded);
|
subnode.to_compact(&mut encoded);
|
||||||
let (decoded, _) = StoredSubNode::from_compact(&encoded[..], 0);
|
let (decoded, _) = StoredSubNode::from_compact(&encoded[..], 0);
|
||||||
|
|
||||||
assert_eq!(subnode, decoded);
|
assert_eq!(subnode, decoded);
|
||||||
|
|||||||
Reference in New Issue
Block a user