use std::{
fmt::{Debug, Display},
hash::Hash,
};
use derive_more::Display;
use serde::{de::DeserializeOwned, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use casper_execution_engine::storage::trie::Trie;
use casper_hashing::Digest;
use casper_types::{bytesrepr::ToBytes, Key, StoredValue};
use crate::types::{BlockHash, BlockHeader, BlockHeaderWithMetadata};
#[derive(
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize_repr,
Deserialize_repr,
Debug,
Display,
)]
#[repr(u8)]
pub enum Tag {
Deploy,
Block,
GossipedAddress,
BlockByHeight,
BlockHeaderByHash,
BlockHeaderAndFinalitySignaturesByHeight,
}
pub trait Item: Clone + Serialize + DeserializeOwned + Send + Sync + Debug + Display {
type Id: Copy + Eq + Hash + Serialize + DeserializeOwned + Send + Sync + Debug + Display;
const TAG: Tag;
const ID_IS_COMPLETE_ITEM: bool;
fn id(&self) -> Self::Id;
}
impl Item for Trie<Key, StoredValue> {
type Id = Digest;
const TAG: Tag = Tag::Deploy;
const ID_IS_COMPLETE_ITEM: bool = false;
fn id(&self) -> Self::Id {
let node_bytes = self.to_bytes().expect("Could not serialize trie to bytes");
Digest::hash(&node_bytes)
}
}
impl Item for BlockHeader {
type Id = BlockHash;
const TAG: Tag = Tag::BlockHeaderByHash;
const ID_IS_COMPLETE_ITEM: bool = false;
fn id(&self) -> Self::Id {
self.hash()
}
}
impl Item for BlockHeaderWithMetadata {
type Id = u64;
const TAG: Tag = Tag::BlockHeaderAndFinalitySignaturesByHeight;
const ID_IS_COMPLETE_ITEM: bool = false;
fn id(&self) -> Self::Id {
self.block_header.height()
}
}