diff --git a/bin/reth/src/db/get.rs b/bin/reth/src/db/get.rs index bc90e4c410..32ede8c7a1 100644 --- a/bin/reth/src/db/get.rs +++ b/bin/reth/src/db/get.rs @@ -95,8 +95,8 @@ mod tests { use super::*; use clap::{Args, Parser}; use reth_db::{ - models::storage_sharded_key::StorageShardedKey, HashedAccount, Headers, StorageHistory, - SyncStage, + models::{storage_sharded_key::StorageShardedKey, ShardedKey}, + AccountHistory, HashedAccount, Headers, StorageHistory, SyncStage, }; use reth_primitives::{H160, H256}; use std::str::FromStr; @@ -148,4 +148,16 @@ mod tests { ) ); } + + #[test] + fn parse_json_key_for_account_history() { + let args = CommandParser::::parse_from(["reth", "AccountHistory", r#"{ "key": "0x4448e1273fd5a8bfdb9ed111e96889c960eee145", "highest_block_number": 18446744073709551615 }"#]).args; + assert_eq!( + args.table_key::().unwrap(), + ShardedKey::new( + H160::from_str("0x4448e1273fd5a8bfdb9ed111e96889c960eee145").unwrap(), + 18446744073709551615 + ) + ); + } } diff --git a/crates/primitives/src/integer_list.rs b/crates/primitives/src/integer_list.rs index 77f12a953b..f4dd5a6ae1 100644 --- a/crates/primitives/src/integer_list.rs +++ b/crates/primitives/src/integer_list.rs @@ -1,13 +1,14 @@ use serde::{ - de::{Unexpected, Visitor}, + de::{SeqAccess, Unexpected, Visitor}, + ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer, }; -use std::ops::Deref; +use std::{fmt, ops::Deref}; use sucds::{EliasFano, Searial}; /// Uses EliasFano to hold a list of integers. It provides really good compression with the /// capability to access its elements without decoding it. -#[derive(Debug, Clone, PartialEq, Eq, Default)] +#[derive(Clone, PartialEq, Eq, Default)] pub struct IntegerList(pub EliasFano); impl Deref for IntegerList { @@ -18,6 +19,13 @@ impl Deref for IntegerList { } } +impl fmt::Debug for IntegerList { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let vec: Vec = self.0.iter(0).collect(); + write!(f, "IntegerList {:?}", vec) + } +} + impl IntegerList { /// Creates an IntegerList from a list of integers. `usize` is safe to use since /// [`sucds::EliasFano`] restricts its compilation to 64bits. @@ -68,7 +76,12 @@ impl Serialize for IntegerList { where S: Serializer, { - serializer.serialize_bytes(&self.to_bytes()) + let vec = self.0.iter(0).collect::>(); + let mut seq = serializer.serialize_seq(Some(self.len()))?; + for e in vec { + seq.serialize_element(&e)?; + } + seq.end() } } @@ -77,15 +90,19 @@ impl<'de> Visitor<'de> for IntegerListVisitor { type Value = IntegerList; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("a byte array") + formatter.write_str("a usize array") } - fn visit_bytes(self, v: &[u8]) -> Result + fn visit_seq(self, mut seq: E) -> Result where - E: serde::de::Error, + E: SeqAccess<'de>, { - IntegerList::from_bytes(v) - .map_err(|_| serde::de::Error::invalid_type(Unexpected::Bytes(v), &self)) + let mut list = Vec::new(); + while let Some(item) = seq.next_element()? { + list.push(item); + } + + IntegerList::new(list).map_err(|_| serde::de::Error::invalid_value(Unexpected::Seq, &self)) } } @@ -140,4 +157,14 @@ mod test { let blist = ef_list.to_bytes(); assert_eq!(IntegerList::from_bytes(&blist).unwrap(), ef_list) } + + #[test] + fn serde_serialize_deserialize() { + let original_list = [1, 2, 3]; + let ef_list = IntegerList::new(original_list).unwrap(); + + let serde_out = serde_json::to_string(&ef_list).unwrap(); + let serde_ef_list = serde_json::from_str::(&serde_out).unwrap(); + assert_eq!(serde_ef_list, ef_list); + } }