Files
lighthouse/crypto/kzg/src/kzg_commitment.rs
Jimmy Chen 70c4ae35ab Merge branch 'unstable' into deneb-free-blobs
# Conflicts:
#	.github/workflows/docker.yml
#	.github/workflows/local-testnet.yml
#	.github/workflows/test-suite.yml
#	Cargo.lock
#	Cargo.toml
#	beacon_node/beacon_chain/src/beacon_chain.rs
#	beacon_node/beacon_chain/src/builder.rs
#	beacon_node/beacon_chain/src/test_utils.rs
#	beacon_node/execution_layer/src/engine_api/json_structures.rs
#	beacon_node/network/src/beacon_processor/mod.rs
#	beacon_node/network/src/beacon_processor/worker/gossip_methods.rs
#	beacon_node/network/src/sync/backfill_sync/mod.rs
#	beacon_node/store/src/config.rs
#	beacon_node/store/src/hot_cold_store.rs
#	common/eth2_network_config/Cargo.toml
#	consensus/ssz/src/decode/impls.rs
#	consensus/ssz_derive/src/lib.rs
#	consensus/ssz_derive/tests/tests.rs
#	consensus/ssz_types/src/serde_utils/mod.rs
#	consensus/tree_hash/src/impls.rs
#	consensus/tree_hash/src/lib.rs
#	consensus/types/Cargo.toml
#	consensus/types/src/beacon_state.rs
#	consensus/types/src/chain_spec.rs
#	consensus/types/src/eth_spec.rs
#	consensus/types/src/fork_name.rs
#	lcli/Cargo.toml
#	lcli/src/main.rs
#	lcli/src/new_testnet.rs
#	scripts/local_testnet/el_bootnode.sh
#	scripts/local_testnet/genesis.json
#	scripts/local_testnet/geth.sh
#	scripts/local_testnet/setup.sh
#	scripts/local_testnet/start_local_testnet.sh
#	scripts/local_testnet/vars.env
#	scripts/tests/doppelganger_protection.sh
#	scripts/tests/genesis.json
#	scripts/tests/vars.env
#	testing/ef_tests/Cargo.toml
#	validator_client/src/block_service.rs
2023-05-30 22:44:05 +10:00

136 lines
3.9 KiB
Rust

use c_kzg::{Bytes48, BYTES_PER_COMMITMENT};
use derivative::Derivative;
use ethereum_hashing::hash_fixed;
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
use ssz_derive::{Decode, Encode};
use std::fmt;
use std::fmt::{Debug, Display, Formatter};
use std::str::FromStr;
use tree_hash::{Hash256, PackedEncoding, TreeHash};
pub const BLOB_COMMITMENT_VERSION_KZG: u8 = 0x01;
#[derive(Derivative, Clone, Copy, Encode, Decode)]
#[derivative(PartialEq, Eq, Hash)]
#[ssz(struct_behaviour = "transparent")]
pub struct KzgCommitment(pub [u8; BYTES_PER_COMMITMENT]);
impl KzgCommitment {
pub fn calculate_versioned_hash(&self) -> Hash256 {
let mut versioned_hash = hash_fixed(&self.0);
versioned_hash[0] = BLOB_COMMITMENT_VERSION_KZG;
Hash256::from_slice(versioned_hash.as_slice())
}
}
impl From<KzgCommitment> for Bytes48 {
fn from(value: KzgCommitment) -> Self {
value.0.into()
}
}
impl Display for KzgCommitment {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", serde_utils::hex::encode(self.0))
}
}
impl Default for KzgCommitment {
fn default() -> Self {
KzgCommitment([0; BYTES_PER_COMMITMENT])
}
}
impl TreeHash for KzgCommitment {
fn tree_hash_type() -> tree_hash::TreeHashType {
<[u8; BYTES_PER_COMMITMENT] as TreeHash>::tree_hash_type()
}
fn tree_hash_packed_encoding(&self) -> PackedEncoding {
self.0.tree_hash_packed_encoding()
}
fn tree_hash_packing_factor() -> usize {
<[u8; BYTES_PER_COMMITMENT] as TreeHash>::tree_hash_packing_factor()
}
fn tree_hash_root(&self) -> tree_hash::Hash256 {
self.0.tree_hash_root()
}
}
impl Serialize for KzgCommitment {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
impl<'de> Deserialize<'de> for KzgCommitment {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
pub struct StringVisitor;
impl<'de> serde::de::Visitor<'de> for StringVisitor {
type Value = String;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a hex string with 0x prefix")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(value.to_string())
}
}
let string = deserializer.deserialize_str(StringVisitor)?;
<Self as std::str::FromStr>::from_str(&string).map_err(serde::de::Error::custom)
}
}
impl FromStr for KzgCommitment {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if let Some(stripped) = s.strip_prefix("0x") {
let bytes = hex::decode(stripped).map_err(|e| e.to_string())?;
if bytes.len() == BYTES_PER_COMMITMENT {
let mut kzg_commitment_bytes = [0; BYTES_PER_COMMITMENT];
kzg_commitment_bytes[..].copy_from_slice(&bytes);
Ok(Self(kzg_commitment_bytes))
} else {
Err(format!(
"InvalidByteLength: got {}, expected {}",
bytes.len(),
BYTES_PER_COMMITMENT
))
}
} else {
Err("must start with 0x".to_string())
}
}
}
impl Debug for KzgCommitment {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", serde_utils::hex::encode(self.0))
}
}
#[cfg(feature = "arbitrary")]
impl arbitrary::Arbitrary<'_> for KzgCommitment {
fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
let mut bytes = [0u8; BYTES_PER_COMMITMENT];
u.fill_buffer(&mut bytes)?;
Ok(KzgCommitment(bytes))
}
}