Struct celestia_types::ExtendedDataSquare
source · pub struct ExtendedDataSquare { /* private fields */ }Expand description
The data matrix in Celestia blocks extended with parity data.
It is created by a fixed size chunks of data, called Shares.
Each share is a cell of the ExtendedDataSquare.
§Structure
The ExtendedDataSquare consists of four quadrants. The first
quadrant (upper-left) is the original data submitted to the network,
referred to as OriginalDataSquare. The other three quadrants are
the parity data encoded row-wise or column-wise using Reed-Solomon
codec specified in EDS.
The below diagram shows how the EDS is constructed. First, the 2nd
and 3rd quadrants are created by computing Reed-Solomon parity data
of the original data square, row-wise for 2nd and column-wise for
3rd quadrant. Then, the 4th quadrant is computed either row-wise
from 3rd or column-wise from 2nd quadrant.
---------------------------
| | |
| --|-> |
| 1 --|-> 2 |
| --|-> |
| | | | | |
-------------+-------------
| v v v | |
| --|-> |
| 3 --|-> 4 |
| --|-> |
| | |
---------------------------
§Data availability
The DataAvailabilityHeader is created by computing Nmt merkle
roots of each row and column of ExtendedDataSquare.
By putting those together there are some key
properties those have in terms of data availability.
Thanks to the parity data, to make original data unrecoverable, a malicious
actor would need to hide more than a half of the data from each row and column.
If we take k as the width of the OriginalDataSquare, then the attacker
needs to hide more than (k + 1)^2 shares from the ExtendedDataSquare.
For the EDS with a width of 4, the attacker needs to hide more than 50% of
all the shares and that value approaches 25% as the square grows.
This allows for really efficient data sampling, as the sampling node can reach very high confidence that whole data is available by taking only a few samples.
§Example
This example shows rebuilding the merkle trees for each row of the EDS and compares them with the root hashes stored in data availability header.
use celestia_types::Share;
let block_height = 15;
let header = get_header(block_height);
let eds = get_eds(block_height);
let width = header.dah.square_width();
// for each row of the data square, build an nmt
for row in 0..eds.square_width() {
// check if the root corresponds to the one from the dah
let root = eds.row_nmt(row).unwrap().root();
assert_eq!(root, header.dah.row_root(row).unwrap());
}Implementations§
source§impl ExtendedDataSquare
impl ExtendedDataSquare
sourcepub fn new(shares: Vec<Vec<u8>>, codec: String) -> Result<Self>
pub fn new(shares: Vec<Vec<u8>>, codec: String) -> Result<Self>
Create a new EDS out of the provided shares.
Shares should be provided in a row-major order, i.e. first shares of the first row, then of the second row and so on.
§Errors
Returns an error if:
- shares are of sizes different than
SHARE_SIZE - amount of shares doesn’t allow for forming a square
- width of the square is smaller than
MIN_EXTENDED_SQUARE_WIDTH - width of the square is bigger than
MAX_EXTENDED_SQUARE_WIDTH - width of the square isn’t a power of 2
- namespaces of shares aren’t in non-decreasing order row and column wise
sourcepub fn empty() -> ExtendedDataSquare
pub fn empty() -> ExtendedDataSquare
Crate a new EDS that represents an empty block
sourcepub fn from_ods(ods_shares: Vec<Vec<u8>>) -> Result<ExtendedDataSquare>
pub fn from_ods(ods_shares: Vec<Vec<u8>>) -> Result<ExtendedDataSquare>
Create a new EDS out of the provided original data square shares.
This method is similar to the ExtendedDataSquare::new but parity data
will be encoded automatically using the leopard_codec
Shares should be provided in a row-major order.
§Errors
The same errors as in ExtendedDataSquare::new applies. The constrain
will be checked after the parity data is generated.
Additionally, this function will propagate any error from encoding parity data.
sourcepub fn data_square(&self) -> &[Vec<u8>]
pub fn data_square(&self) -> &[Vec<u8>]
The raw data of the EDS.
Returns the share of the provided coordinates.
sourcepub fn axis(&self, axis: AxisType, index: u16) -> Result<Vec<Vec<u8>>>
pub fn axis(&self, axis: AxisType, index: u16) -> Result<Vec<Vec<u8>>>
Returns the shares of column or row.
sourcepub fn axis_nmt(&self, axis: AxisType, index: u16) -> Result<Nmt>
pub fn axis_nmt(&self, axis: AxisType, index: u16) -> Result<Nmt>
Returns the Nmt of column or row.
sourcepub fn square_width(&self) -> u16
pub fn square_width(&self) -> u16
Get EDS square length.
sourcepub fn get_namespaced_data(
&self,
namespace: Namespace,
dah: &DataAvailabilityHeader,
height: u64,
) -> Result<Vec<NamespacedData>>
pub fn get_namespaced_data( &self, namespace: Namespace, dah: &DataAvailabilityHeader, height: u64, ) -> Result<Vec<NamespacedData>>
Return all the shares that belong to the provided namespace in the EDS. Results are returned as a list of rows of shares with the inclusion proof.
Trait Implementations§
source§impl Clone for ExtendedDataSquare
impl Clone for ExtendedDataSquare
source§fn clone(&self) -> ExtendedDataSquare
fn clone(&self) -> ExtendedDataSquare
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moresource§impl Debug for ExtendedDataSquare
impl Debug for ExtendedDataSquare
source§impl<'de> Deserialize<'de> for ExtendedDataSquare
impl<'de> Deserialize<'de> for ExtendedDataSquare
source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
source§impl PartialEq for ExtendedDataSquare
impl PartialEq for ExtendedDataSquare
source§impl Serialize for ExtendedDataSquare
impl Serialize for ExtendedDataSquare
impl Eq for ExtendedDataSquare
impl StructuralPartialEq for ExtendedDataSquare
Auto Trait Implementations§
impl Freeze for ExtendedDataSquare
impl RefUnwindSafe for ExtendedDataSquare
impl Send for ExtendedDataSquare
impl Sync for ExtendedDataSquare
impl Unpin for ExtendedDataSquare
impl UnwindSafe for ExtendedDataSquare
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit)