Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: sealed #467

Merged
merged 4 commits into from
Dec 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ pub use self::bytes_::Bytes;
mod log;
pub use log::Log;

mod sealed;
pub use sealed::{Sealable, Sealed};

mod signed;
pub use signed::{BigIntConversionError, ParseSignedError, Sign, Signed};

Expand Down
82 changes: 82 additions & 0 deletions crates/primitives/src/sealed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use crate::B256;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
prestwich marked this conversation as resolved.
Show resolved Hide resolved
/// A consensus hashable item, with its memoized hash.
///
/// We do not implement
prestwich marked this conversation as resolved.
Show resolved Hide resolved
pub struct Sealed<T> {
/// The inner item
inner: T,
/// Its hash.
seal: B256,
}

impl<T> core::ops::Deref for Sealed<T> {
type Target = T;

fn deref(&self) -> &Self::Target {
self.inner()
}
}

impl<T> Sealed<T> {
/// Instantiate without performing the hash. This should be used carefully.
pub const fn new_unchecked(inner: T, seal: B256) -> Self {
Self { inner, seal }
}
/// Decompose into parts.
#[allow(clippy::missing_const_for_fn)] // false positive
pub fn into_parts(self) -> (T, B256) {
(self.inner, self.seal)
}

/// Decompose into parts. Alias for [`Self::into_parts`].
#[allow(clippy::missing_const_for_fn)] // false positive
pub fn split(self) -> (T, B256) {
self.into_parts()
}

/// Get the inner item.
#[inline(always)]
pub const fn inner(&self) -> &T {
&self.inner
}

/// Get the hash.
#[inline(always)]
pub const fn seal(&self) -> B256 {
self.seal
}

/// Unseal the inner item, discarding the hash.
#[inline(always)]
#[allow(clippy::missing_const_for_fn)] // false positive
pub fn into_inner(self) -> T {
self.inner
}

/// Unseal the inner item, discarding the hash. Alias for
/// [`Self::into_inner`].
#[inline(always)]
#[allow(clippy::missing_const_for_fn)] // false positive
pub fn unseal(self) -> T {
self.into_inner()
}
}

/// Sealeable objects.
pub trait Sealable: Sized {
/// Calculate the seal hash, this may be slow.
fn hash_slow(&self) -> B256;

/// Seal the object by calculating the hash. This may be slow.
fn seal_slow(self) -> Sealed<Self> {
let seal = self.hash_slow();
Sealed::new_unchecked(self, seal)
}

/// Instantiate an unchecked seal. This should be used with caution.
fn seal_unchecked(self, seal: B256) -> Sealed<Self> {
Sealed::new_unchecked(self, seal)
}
}