Skip to content

Commit

Permalink
Unify HashedCertificateValue with Hashed<T>
Browse files Browse the repository at this point in the history
  • Loading branch information
deuszx committed Nov 11, 2024
1 parent 7431f43 commit 25b18e0
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 34 deletions.
3 changes: 1 addition & 2 deletions linera-chain/src/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,10 @@ impl From<TimeoutCertificate> for Certificate {
}
}

// In practice, it should be HashedCertificateValue = Hashed<CertificateValue>
// but [`HashedCertificateValue`] is used in too many places to change it now.
/// Wrapper type around hashed instance of `T` type.
pub struct Hashed<T> {
value: T,
/// Hash of the value (used as key for storage).
hash: CryptoHash,
}

Expand Down
60 changes: 28 additions & 32 deletions linera-chain/src/data_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ use linera_execution::{
};
use serde::{de::Deserializer, Deserialize, Serialize};

use crate::{types::ValidatedBlockCertificate, ChainError};
use crate::{
types::{Hashed, ValidatedBlockCertificate},
ChainError,
};

#[cfg(test)]
#[path = "unit_tests/data_types_tests.rs"]
Expand Down Expand Up @@ -423,26 +426,31 @@ impl CertificateValue {
}

/// A statement to be certified by the validators, with its hash.
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct HashedCertificateValue {
value: CertificateValue,
/// Hash of the value (used as key for storage).
hash: CryptoHash,
}
pub type HashedCertificateValue = Hashed<CertificateValue>;

#[async_graphql::Object(cache_control(no_cache))]
impl HashedCertificateValue {
#[graphql(derived(name = "hash"))]
async fn _hash(&self) -> CryptoHash {
self.hash
self.hash()
}

#[graphql(derived(name = "value"))]
async fn _value(&self) -> CertificateValue {
self.value.clone()
self.inner().clone()
}
}

#[cfg(with_testing)]
impl<T> PartialEq for Hashed<T> {
fn eq(&self, other: &Self) -> bool {
self.hash() == other.hash()
}
}

#[cfg(with_testing)]
impl<T> Eq for Hashed<T> {}

/// The hash and chain ID of a `CertificateValue`.
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
pub struct LiteValue {
Expand All @@ -465,7 +473,7 @@ pub struct Vote {
impl Vote {
/// Use signing key to create a signed object.
pub fn new(value: HashedCertificateValue, round: Round, key_pair: &KeyPair) -> Self {
let hash_and_round = ValueHashAndRound(value.hash, round);
let hash_and_round = ValueHashAndRound(value.hash(), round);
let signature = Signature::new(&hash_and_round, key_pair);
Self {
value,
Expand Down Expand Up @@ -656,7 +664,7 @@ impl Serialize for HashedCertificateValue {
where
S: serde::Serializer,
{
self.value.serialize(serializer)
self.inner().serialize(serializer)
}
}

Expand All @@ -677,7 +685,7 @@ impl From<CertificateValue> for HashedCertificateValue {

impl From<HashedCertificateValue> for CertificateValue {
fn from(hv: HashedCertificateValue) -> CertificateValue {
hv.value
hv.into_inner()
}
}

Expand Down Expand Up @@ -714,10 +722,10 @@ impl CertificateValue {
pub fn with_hash_checked(self, hash: CryptoHash) -> Result<HashedCertificateValue, ChainError> {
let hashed_certificate_value = self.with_hash();
ensure!(
hashed_certificate_value.hash == hash,
hashed_certificate_value.hash() == hash,
ChainError::CertificateValueHashMismatch {
expected: hash,
actual: hashed_certificate_value.hash
actual: hashed_certificate_value.hash()
}
);
Ok(hashed_certificate_value)
Expand All @@ -726,12 +734,12 @@ impl CertificateValue {
/// Creates a `HashedCertificateValue` by hashing `self`. No hash checks are made!
pub fn with_hash(self) -> HashedCertificateValue {
let hash = CryptoHash::new(&self);
HashedCertificateValue { value: self, hash }
HashedCertificateValue::unchecked_new(self, hash)
}

/// Creates a `HashedCertificateValue` without checking that this is the correct hash!
pub fn with_hash_unchecked(self, hash: CryptoHash) -> HashedCertificateValue {
HashedCertificateValue { value: self, hash }
HashedCertificateValue::unchecked_new(self, hash)
}

/// Returns whether this value contains the message with the specified ID.
Expand Down Expand Up @@ -992,34 +1000,22 @@ impl HashedCertificateValue {
.into()
}

pub fn hash(&self) -> CryptoHash {
self.hash
}

pub fn lite(&self) -> LiteValue {
LiteValue {
value_hash: self.hash(),
chain_id: self.value.chain_id(),
chain_id: self.inner().chain_id(),
}
}

/// Returns the corresponding `ConfirmedBlock`, if this is a `ValidatedBlock`.
pub fn validated_to_confirmed(&self) -> Option<HashedCertificateValue> {
match &self.value {
match self.inner() {
CertificateValue::ValidatedBlock { executed_block } => Some(
HashedCertificateValue::new_confirmed(executed_block.clone()),
),
CertificateValue::ConfirmedBlock { .. } | CertificateValue::Timeout { .. } => None,
}
}

pub fn inner(&self) -> &CertificateValue {
&self.value
}

pub fn into_inner(self) -> CertificateValue {
self.value
}
}

/// The data a block proposer signs.
Expand Down Expand Up @@ -1251,12 +1247,12 @@ impl Certificate {

/// Returns the certified value.
pub fn value(&self) -> &CertificateValue {
&self.value.value
self.value.inner()
}

/// Returns the certified value's hash.
pub fn hash(&self) -> CryptoHash {
self.value.hash
self.value.hash()
}

/// Returns whether the validator is among the signatories of this certificate.
Expand Down

0 comments on commit 25b18e0

Please sign in to comment.