use alloy_primitives::{Address, B256};
use alloy_rpc_types_engine::PayloadStatusEnum;
use serde::{ser::SerializeMap, Deserialize, Serialize, Serializer};
use std::fmt;
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InclusionListStatusV1 {
#[serde(flatten)]
pub status: PayloadStatusEnum,
}
impl InclusionListStatusV1 {
pub const fn new(status: PayloadStatusEnum) -> Self {
Self { status }
}
pub const fn is_syncing(&self) -> bool {
self.status.is_syncing()
}
pub const fn is_valid(&self) -> bool {
self.status.is_valid()
}
pub const fn is_invalid(&self) -> bool {
self.status.is_invalid()
}
}
impl fmt::Display for InclusionListStatusV1 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "InclusionListStatusV1 {{ status: {} }}", self.status)
}
}
impl Serialize for InclusionListStatusV1 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map = serializer.serialize_map(Some(3))?;
map.serialize_entry("status", self.status.as_str())?;
map.serialize_entry("validationError", &self.status.validation_error())?;
map.end()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InclusionListSummaryEntryV1 {
pub address: Address,
#[serde(with = "alloy_serde::quantity")]
pub nonce: u64,
}
impl fmt::Display for InclusionListSummaryEntryV1 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "InclusionListEntryV1 {{ address: {}, nonce: {} }}", self.address, self.nonce)
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InclusionListSummaryV1 {
#[serde(with = "alloy_serde::quantity")]
pub slot: u64,
#[serde(with = "alloy_serde::quantity")]
pub proposer_index: u64,
pub parent_hash: B256,
pub summary: Vec<InclusionListSummaryEntryV1>,
}
#[cfg(test)]
mod tests {
use super::*;
use alloy_primitives::hex::FromHex;
use serde_json::json;
#[test]
fn inclusion_list_status_v1_serialization() {
let status = InclusionListStatusV1::new(PayloadStatusEnum::Valid);
let json = json!({
"status": "VALID",
"validationError": null,
});
assert_eq!(serde_json::to_value(status).unwrap(), json);
}
#[test]
fn inclusion_list_entry_v1_serialization() {
let entry = InclusionListSummaryEntryV1 {
address: Address::from_hex("0x0000000000000000000000000000000000000042").unwrap(),
nonce: 42,
};
let json = json!({
"address": "0x0000000000000000000000000000000000000042",
"nonce": "0x2a",
});
assert_eq!(serde_json::to_value(entry).unwrap(), json);
}
#[test]
fn inclusion_list_summary_v1_serialization() {
let summary = InclusionListSummaryV1 {
slot: 42,
proposer_index: 42,
parent_hash: B256::from_hex(
"0x2222222222222222222222222222222222222222222222222222222222222222",
)
.unwrap(),
summary: vec![
InclusionListSummaryEntryV1 {
address: Address::from_hex("0x0000000000000000000000000000000000000042")
.unwrap(),
nonce: 42,
},
InclusionListSummaryEntryV1 {
address: Address::from_hex("0x0000000000000000000000000000000000000043")
.unwrap(),
nonce: 43,
},
],
};
let json = json!({
"slot": "0x2a",
"proposerIndex": "0x2a",
"parentHash": "0x2222222222222222222222222222222222222222222222222222222222222222",
"summary": [
{
"address": "0x0000000000000000000000000000000000000042",
"nonce": "0x2a",
},
{
"address": "0x0000000000000000000000000000000000000043",
"nonce": "0x2b",
},
],
});
assert_eq!(serde_json::to_value(summary).unwrap(), json);
}
}