Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
zvolin committed Dec 7, 2023
1 parent 25de58a commit 4a42e11
Show file tree
Hide file tree
Showing 10 changed files with 348 additions and 31 deletions.
2 changes: 1 addition & 1 deletion types/src/blob/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::{InfoByte, Share};
/// root as shown below:
///
/// ```text
/// row root
/// NMT: row root
/// / \
/// o subtree root
/// / \ / \
Expand Down
3 changes: 3 additions & 0 deletions types/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{bail_validation, Error, Result, ValidateBasic, ValidationError};

pub(crate) const GENESIS_HEIGHT: u64 = 1;

/// The height of the block in Celestia network.
pub type Height = tendermint::block::Height;

impl ValidateBasic for Header {
Expand Down Expand Up @@ -95,7 +96,9 @@ impl ValidateBasic for CommitSig {
}
}

/// An extention trait for the [`Commit`] to perform additional actions.
pub trait CommitExt {
/// Get the signed [`Vote`] from the [`Commit`] at the given index.
fn vote_sign_bytes(&self, chain_id: &chain::Id, signature_idx: usize) -> Result<Vec<u8>>;
}

Expand Down
14 changes: 14 additions & 0 deletions types/src/byzantine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ pub const MULTIHASH_SHA256_NAMESPACE_FLAGGED_SIZE: usize = 2 * NS_SIZE + SHA256_
type Cid = CidGeneric<MULTIHASH_SHA256_NAMESPACE_FLAGGED_SIZE>;
type Multihash = MultihashGeneric<MULTIHASH_SHA256_NAMESPACE_FLAGGED_SIZE>;

/// A proof that the block producer incorrectly encoded [`ExtendedDataSquare`].
///
/// Some malicious actor may incorrectly extend the original data with the
/// recovery data, thus making it impossible to reconstruct the original
/// information.
///
/// Light node cannot detect such behaviour with [`Data Availability Sampling`].
/// When the full node collects all the [`Share`]s of a row or column of the [`ExtendedDataSquare`]
/// and detects that it was incorrectly encoded, it should create and announce
/// [`BadEncodingFraudProof`] so that light nodes can reject this block.
///
/// [`Data Availability Sampling`]: https://docs.celestia.org/learn/how-celestia-works/data-availability-layer
/// [`ExtendedDataSquare`]: crate::ExtendedDataSquare
/// [`Share`]: crate::share::Share
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(
try_from = "RawBadEncodingFraudProof",
Expand Down
53 changes: 35 additions & 18 deletions types/src/consts.rs
Original file line number Diff line number Diff line change
@@ -1,88 +1,105 @@
//! Constants used within celestia ecosystem.
/// The size of the SHA256 hash.
pub const HASH_SIZE: usize = tendermint::hash::SHA256_HASH_SIZE;

// celestia-core/types/genesis
/// Constants related to genesis definition.
pub mod genesis {
/// Max length of the chain ID.
pub const MAX_CHAIN_ID_LEN: usize = 50;
}

// celestia-core/version/version
/// Constants related to the protocol versions.
pub mod version {
// BLOCK_PROTOCOL versions all block data structures and processing.
// This includes validity of blocks and state updates.
/// Version of all the block data structures and processing.
///
/// This includes validity of blocks and state updates.
pub const BLOCK_PROTOCOL: u64 = 11;
}

/// Constants defined in [`celestia-app`] consensus nodes.
///
/// [`celestia-app`]: https://github.com/celestiaorg/celestia-app
pub mod appconsts {
pub use global_consts::*;
pub use v1::*;

// celestia-app/pkg/appconsts/v1/app_consts
mod v1 {
/// Maximum width of a single subtree root when generating blob's commitment.
pub const SUBTREE_ROOT_THRESHOLD: u64 = 64;
/// Maximum width of the original data square.
pub const SQUARE_SIZE_UPPER_BOUND: usize = 128;
}

// celestia-app/pkg/appconsts/global_consts
mod global_consts {
use crate::nmt::NS_SIZE;

/// the size of the namespace.
/// The size of the namespace.
pub const NAMESPACE_SIZE: usize = NS_SIZE;

/// the size of a share in bytes.
/// The size of a share in bytes.
pub const SHARE_SIZE: usize = 512;

/// the number of bytes reserved for information. The info
/// byte contains the share version and a sequence start idicator.
/// The number of bytes reserved for the share metadata.
///
/// The info byte contains the share version and a sequence start idicator.
pub const SHARE_INFO_BYTES: usize = 1;

/// the number of bytes reserved for the sequence length
/// that is present in the first share of a sequence.
/// The number of bytes reserved for the sequence length in a share.
///
/// That is present in the first share of a sequence.
pub const SEQUENCE_LEN_BYTES: usize = 4;

/// the first share version format.
/// The first share version format.
pub const SHARE_VERSION_ZERO: u8 = 0;

/// the number of bytes reserved for the location of
/// the first unit (transaction, ISR) in a compact share.
/// The number of bytes reserved for the location of the first unit (transaction, ISR) in a compact share.
pub const COMPACT_SHARE_RESERVED_BYTES: usize = 4;

/// the number of bytes usable for data in the first compact share of a sequence.
/// The number of bytes usable for data in the first compact share of a sequence.
pub const FIRST_COMPACT_SHARE_CONTENT_SIZE: usize = SHARE_SIZE
- NAMESPACE_SIZE
- SHARE_INFO_BYTES
- SEQUENCE_LEN_BYTES
- COMPACT_SHARE_RESERVED_BYTES;

/// the number of bytes usable for data in a continuation compact share of a sequence.
/// The number of bytes usable for data in a continuation compact share of a sequence.
pub const CONTINUATION_COMPACT_SHARE_CONTENT_SIZE: usize =
SHARE_SIZE - NAMESPACE_SIZE - SHARE_INFO_BYTES - COMPACT_SHARE_RESERVED_BYTES;

/// the number of bytes usable for data in the first sparse share of a sequence.
/// The number of bytes usable for data in the first sparse share of a sequence.
pub const FIRST_SPARSE_SHARE_CONTENT_SIZE: usize =
SHARE_SIZE - NAMESPACE_SIZE - SHARE_INFO_BYTES - SEQUENCE_LEN_BYTES;

/// the number of bytes usable for data in a continuation sparse share of a sequence.
/// The number of bytes usable for data in a continuation sparse share of a sequence.
pub const CONTINUATION_SPARSE_SHARE_CONTENT_SIZE: usize =
SHARE_SIZE - NAMESPACE_SIZE - SHARE_INFO_BYTES;

/// the smallest original square width.
/// The smallest original square width.
pub const MIN_SQUARE_SIZE: usize = 1;

/// the minimum number of shares allowed in the original data square.
/// The minimum number of shares allowed in the original data square.
pub const MIN_SHARE_COUNT: usize = MIN_SQUARE_SIZE * MIN_SQUARE_SIZE;

/// the maximum value a share version can be.
/// The maximum value a share version can be.
pub const MAX_SHARE_VERSION: u8 = 127;
}
}

// celestia-app/pkg/da/data_availability_header
/// Constants related to the [`DataAvailabilityHeader`].
///
/// [`DataAvailabilityHeader`]: crate::DataAvailabilityHeader
pub mod data_availability_header {
pub const MAX_EXTENDED_SQUARE_WIDTH: usize = super::appconsts::SQUARE_SIZE_UPPER_BOUND * 2;
pub const MIN_EXTENDED_SQUARE_WIDTH: usize = super::appconsts::MIN_SQUARE_SIZE * 2;
}

/// Constants related to the underlying cosmos sdk.
pub mod cosmos {
use const_format::concatcp;

Expand Down
59 changes: 59 additions & 0 deletions types/src/data_availability_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,84 @@ use crate::hash::Hash;
use crate::nmt::{NamespacedHash, NamespacedHashExt};
use crate::{bail_validation, Error, Result, ValidateBasic, ValidationError};

/// Header with commitments of the data availability.
///
/// It consists of the root hashes of the merkle trees created from each
/// row and column of the [`ExtendedDataSquare`]. Those are used to prove
/// the inclusion of the data in a block.
///
/// The hash of this header is a hash of all rows and columns and thus a
/// data commitment of the block.
///
/// # Example
///
/// ```no_run
/// # use celestia_types::{ExtendedHeader, Height, Share};
/// # use celestia_types::nmt::{Namespace, NamespaceProof};
/// # fn extended_header() -> ExtendedHeader {
/// # unimplemented!();
/// # }
/// # fn shares_with_proof(_: Height, _: &Namespace) -> (Vec<Share>, NamespaceProof) {
/// # unimplemented!();
/// # }
/// // fetch the block header and data for your namespace
/// let namespace = Namespace::new_v0(&[1, 2, 3, 4]).unwrap();
/// let eh = extended_header();
/// let (shares, proof) = shares_with_proof(eh.height(), &namespace);
///
/// // get the data commitment for a given row
/// let dah = eh.dah;
/// let root = dah.row_root(0).unwrap();
///
/// // verify a proof of the inclusion of the shares
/// assert!(proof.verify_complete_namespace(&root, &shares, *namespace).is_ok());
/// ```
///
/// [`ExtendedDataSquare`]: crate::rsmt2d::ExtendedDataSquare
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(
try_from = "RawDataAvailabilityHeader",
into = "RawDataAvailabilityHeader"
)]
pub struct DataAvailabilityHeader {
/// Merkle roots of the [`ExtendedDataSquare`] rows.
///
/// [`ExtendedDataSquare`]: crate::rsmt2d::ExtendedDataSquare
pub row_roots: Vec<NamespacedHash>,
/// Merkle roots of the [`ExtendedDataSquare`] columns.
///
/// [`ExtendedDataSquare`]: crate::rsmt2d::ExtendedDataSquare
pub column_roots: Vec<NamespacedHash>,
}

impl DataAvailabilityHeader {
/// Get the root of a row with the given index.
pub fn row_root(&self, row: usize) -> Option<NamespacedHash> {
self.row_roots.get(row).cloned()
}

/// Get the root of a column with the given index.
pub fn column_root(&self, column: usize) -> Option<NamespacedHash> {
self.column_roots.get(column).cloned()
}

/// Compute the combined hash of all rows and columns.
///
/// This is the data commitment for the block.
///
/// # Example
///
/// ```
/// # use celestia_types::ExtendedHeader;
/// # fn get_extended_header() -> ExtendedHeader {
/// # let s = include_str!("../test_data/chain1/extended_header_block_1.json");
/// # serde_json::from_str(s).unwrap()
/// # }
/// let eh = get_extended_header();
/// let dah = eh.dah;
///
/// assert_eq!(dah.hash(), eh.header.data_hash);
/// ```
pub fn hash(&self) -> Hash {
let all_roots: Vec<_> = self
.row_roots
Expand Down
16 changes: 14 additions & 2 deletions types/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::consts::appconsts;

/// Alias for a `Result` with the error type [`celestia_types::Error`].
pub type Result<T, E = Error> = std::result::Result<T, E>;

/// Representation of all the errors that can occur when interacting with [`celestia_types`].
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Unsupported namesapce version: {0}")]
Expand Down Expand Up @@ -104,18 +106,28 @@ pub enum Error {
UnsupportedFraudProofType(String),
}

/// Representation of the errors that can occur when validating data.
///
/// See [`ValidateBasic`]
///
/// [`ValidateBasic`]: crate::ValidateBasic
#[derive(Debug, thiserror::Error)]
pub enum ValidationError {
#[error("Not enought voiting power (got {0}, needed {1})")]
#[error("Not enought voting power (got {0}, needed {1})")]
NotEnoughVotingPower(u64, u64),

#[error("{0}")]
Other(String),
}

/// Representation of the errors that can occur when verifying data.
///
/// See [`ExtendedHeader::verify`].
///
/// [`ExtendedHeader::verify`]: crate::ExtendedHeader::verify
#[derive(Debug, thiserror::Error)]
pub enum VerificationError {
#[error("Not enought voiting power (got {0}, needed {1})")]
#[error("Not enought voting power (got {0}, needed {1})")]
NotEnoughVotingPower(u64, u64),

#[error("{0}")]
Expand Down
Loading

0 comments on commit 4a42e11

Please sign in to comment.