mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
Implement Compact codec for alloy_primitives::Log (#7474)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -6237,6 +6237,7 @@ dependencies = [
|
|||||||
"proptest-derive",
|
"proptest-derive",
|
||||||
"reth-codecs-derive",
|
"reth-codecs-derive",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"test-fuzz",
|
"test-fuzz",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@ alloy-eips.workspace = true
|
|||||||
enr = { workspace = true, features = ["rust-secp256k1"] }
|
enr = { workspace = true, features = ["rust-secp256k1"] }
|
||||||
|
|
||||||
# crypto
|
# crypto
|
||||||
secp256k1 = { workspace = true, features = ["global-context", "recovery"] }
|
secp256k1 = { workspace = true, features = ["global-context", "recovery", "rand"] }
|
||||||
# for eip-4844
|
# for eip-4844
|
||||||
c-kzg = { workspace = true, features = ["serde"], optional = true }
|
c-kzg = { workspace = true, features = ["serde"], optional = true }
|
||||||
|
|
||||||
|
|||||||
@ -51,3 +51,27 @@ where
|
|||||||
}
|
}
|
||||||
bloom
|
bloom
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use proptest::proptest;
|
||||||
|
|
||||||
|
proptest! {
|
||||||
|
#[test]
|
||||||
|
fn test_roundtrip_conversion_between_log_and_alloy_log(log: Log) {
|
||||||
|
// Convert log to buffer and then create alloy_log from buffer and compare
|
||||||
|
let mut compacted_log = Vec::<u8>::new();
|
||||||
|
let len = log.clone().to_compact(&mut compacted_log);
|
||||||
|
|
||||||
|
let alloy_log = AlloyLog::from_compact(&compacted_log, len).0;
|
||||||
|
assert_eq!(log, alloy_log.into());
|
||||||
|
|
||||||
|
// Create alloy_log from log and then convert it to buffer and compare compacted_alloy_log and compacted_log
|
||||||
|
let alloy_log = AlloyLog::new_unchecked(log.address, log.topics, log.data);
|
||||||
|
let mut compacted_alloy_log = Vec::<u8>::new();
|
||||||
|
let _len = alloy_log.to_compact(&mut compacted_alloy_log);
|
||||||
|
assert_eq!(compacted_log, compacted_alloy_log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ alloy-primitives = { workspace = true, features = ["arbitrary", "serde"] }
|
|||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
modular-bitfield = "0.11.2"
|
modular-bitfield = "0.11.2"
|
||||||
test-fuzz.workspace = true
|
test-fuzz.workspace = true
|
||||||
|
serde_json.workspace = true
|
||||||
|
|
||||||
arbitrary = { workspace = true, features = ["derive"] }
|
arbitrary = { workspace = true, features = ["derive"] }
|
||||||
proptest.workspace = true
|
proptest.workspace = true
|
||||||
|
|||||||
94
crates/storage/codecs/src/alloy/log.rs
Normal file
94
crates/storage/codecs/src/alloy/log.rs
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
use crate::Compact;
|
||||||
|
use alloy_primitives::{Address, Bytes, Log, LogData};
|
||||||
|
use bytes::BufMut;
|
||||||
|
|
||||||
|
/// Implement `Compact` for `LogData` and `Log`.
|
||||||
|
impl Compact for LogData {
|
||||||
|
fn to_compact<B>(self, buf: &mut B) -> usize
|
||||||
|
where
|
||||||
|
B: BufMut + AsMut<[u8]>,
|
||||||
|
{
|
||||||
|
let mut buffer = bytes::BytesMut::new();
|
||||||
|
let (topics, data) = self.split();
|
||||||
|
topics.specialized_to_compact(&mut buffer);
|
||||||
|
data.to_compact(&mut buffer);
|
||||||
|
let total_length = buffer.len();
|
||||||
|
buf.put(buffer);
|
||||||
|
total_length
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_compact(mut buf: &[u8], _: usize) -> (Self, &[u8]) {
|
||||||
|
let (topics, new_buf) = Vec::specialized_from_compact(buf, buf.len());
|
||||||
|
buf = new_buf;
|
||||||
|
let (data, buf) = Bytes::from_compact(buf, buf.len());
|
||||||
|
let log_data = LogData::new_unchecked(topics, data);
|
||||||
|
(log_data, buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Compact for Log {
|
||||||
|
fn to_compact<B>(self, buf: &mut B) -> usize
|
||||||
|
where
|
||||||
|
B: BufMut + AsMut<[u8]>,
|
||||||
|
{
|
||||||
|
let mut buffer = bytes::BytesMut::new();
|
||||||
|
self.address.to_compact(&mut buffer);
|
||||||
|
self.data.to_compact(&mut buffer);
|
||||||
|
let total_length = buffer.len();
|
||||||
|
buf.put(buffer);
|
||||||
|
total_length
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_compact(mut buf: &[u8], _: usize) -> (Self, &[u8]) {
|
||||||
|
let (address, new_buf) = Address::from_compact(buf, buf.len());
|
||||||
|
buf = new_buf;
|
||||||
|
let (log_data, new_buf) = LogData::from_compact(buf, buf.len());
|
||||||
|
buf = new_buf;
|
||||||
|
let log = Log { address, data: log_data };
|
||||||
|
(log, buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::{Compact, Log};
|
||||||
|
use alloy_primitives::{Address, Bytes, LogData, B256};
|
||||||
|
use proptest::proptest;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
proptest! {
|
||||||
|
#[test]
|
||||||
|
fn roundtrip(log: Log) {
|
||||||
|
let mut buf = Vec::<u8>::new();
|
||||||
|
let len = log.clone().to_compact(&mut buf);
|
||||||
|
let (decoded, _) = Log::from_compact(&buf, len);
|
||||||
|
assert_eq!(log, decoded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct CompactLogTestVector {
|
||||||
|
topics: Vec<B256>,
|
||||||
|
address: Address,
|
||||||
|
data: Bytes,
|
||||||
|
encoded_bytes: Bytes,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_compact_log_codec() {
|
||||||
|
let test_vectors: Vec<CompactLogTestVector> =
|
||||||
|
serde_json::from_str(include_str!("../../testdata/log_compact.json")).unwrap();
|
||||||
|
|
||||||
|
for test_vector in test_vectors {
|
||||||
|
let log_data = LogData::new_unchecked(test_vector.topics, test_vector.data);
|
||||||
|
let log = Log { address: test_vector.address, data: log_data };
|
||||||
|
|
||||||
|
let mut buf = Vec::<u8>::new();
|
||||||
|
let len = log.clone().to_compact(&mut buf);
|
||||||
|
assert_eq!(test_vector.encoded_bytes, buf);
|
||||||
|
|
||||||
|
let (decoded, _) = Log::from_compact(&test_vector.encoded_bytes, len);
|
||||||
|
assert_eq!(log, decoded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
crates/storage/codecs/src/alloy/mod.rs
Normal file
1
crates/storage/codecs/src/alloy/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
mod log;
|
||||||
@ -16,6 +16,8 @@ pub use reth_codecs_derive::*;
|
|||||||
use alloy_primitives::{Address, Bloom, Bytes, B256, B512, U256};
|
use alloy_primitives::{Address, Bloom, Bytes, B256, B512, U256};
|
||||||
use bytes::Buf;
|
use bytes::Buf;
|
||||||
|
|
||||||
|
mod alloy;
|
||||||
|
|
||||||
/// Trait that implements the `Compact` codec.
|
/// Trait that implements the `Compact` codec.
|
||||||
///
|
///
|
||||||
/// When deriving the trait for custom structs, be aware of certain limitations/recommendations:
|
/// When deriving the trait for custom structs, be aware of certain limitations/recommendations:
|
||||||
|
|||||||
2397
crates/storage/codecs/testdata/log_compact.json
vendored
Normal file
2397
crates/storage/codecs/testdata/log_compact.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user