Skip to content

Commit

Permalink
v1.18: shred: expose chained merkle root (backport of #435) (#459)
Browse files Browse the repository at this point in the history
shred: expose chained merkle root (#435)

* shred: expose chained merkle root

* pr feedback: macro, pub(super), _=> none

(cherry picked from commit cfd5b71)

Co-authored-by: Ashwin Sekar <[email protected]>
  • Loading branch information
2 people authored and willhickey committed Mar 29, 2024
1 parent f115169 commit a0bf2d6
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 1 deletion.
32 changes: 32 additions & 0 deletions ledger/src/shred.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ impl ErasureSetId {
macro_rules! dispatch {
($vis:vis fn $name:ident(&self $(, $arg:ident : $ty:ty)?) $(-> $out:ty)?) => {
#[inline]
#[allow(dead_code)]
$vis fn $name(&self $(, $arg:$ty)?) $(-> $out)? {
match self {
Self::ShredCode(shred) => shred.$name($($arg, )?),
Expand Down Expand Up @@ -344,6 +345,7 @@ impl Shred {
dispatch!(fn set_signature(&mut self, signature: Signature));
dispatch!(fn signed_data(&self) -> Result<SignedData, Error>);

dispatch!(pub(crate) fn chained_merkle_root(&self) -> Result<Hash, Error>);
// Returns the portion of the shred's payload which is erasure coded.
dispatch!(pub(crate) fn erasure_shard(self) -> Result<Vec<u8>, Error>);
// Like Shred::erasure_shard but returning a slice.
Expand Down Expand Up @@ -726,6 +728,36 @@ pub mod layout {
}
}

#[allow(dead_code)]
pub(crate) fn get_chained_merkle_root(shred: &[u8]) -> Option<Hash> {
let offset = match get_shred_variant(shred).ok()? {
ShredVariant::LegacyCode | ShredVariant::LegacyData => None,
ShredVariant::MerkleCode {
proof_size,
chained: true,
resigned,
} => merkle::ShredCode::get_chained_merkle_root_offset(proof_size, resigned).ok(),
ShredVariant::MerkleData {
proof_size,
chained: true,
resigned,
} => merkle::ShredData::get_chained_merkle_root_offset(proof_size, resigned).ok(),
ShredVariant::MerkleCode {
proof_size: _,
chained: false,
resigned: _,
} => None,
ShredVariant::MerkleData {
proof_size: _,
chained: false,
resigned: _,
} => None,
}?;
shred
.get(offset..offset + SIZE_OF_MERKLE_ROOT)
.map(Hash::new)
}

// Minimally corrupts the packet so that the signature no longer verifies.
#[cfg(test)]
pub(crate) fn corrupt_packet<R: Rng>(
Expand Down
24 changes: 23 additions & 1 deletion ledger/src/shred/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,24 @@ impl ShredData {
else {
return Err(Error::InvalidShredVariant);
};
Self::get_chained_merkle_root_offset(proof_size, resigned)
}

pub(super) fn get_chained_merkle_root_offset(
proof_size: u8,
resigned: bool,
) -> Result<usize, Error> {
Ok(Self::SIZE_OF_HEADERS + Self::capacity(proof_size, /*chained:*/ true, resigned)?)
}

pub(super) fn chained_merkle_root(&self) -> Result<Hash, Error> {
let offset = self.chained_merkle_root_offset()?;
self.payload
.get(offset..offset + SIZE_OF_MERKLE_ROOT)
.map(Hash::new)
.ok_or(Error::InvalidPayloadSize(self.payload.len()))
}

fn set_chained_merkle_root(&mut self, chained_merkle_root: &Hash) -> Result<(), Error> {
let offset = self.chained_merkle_root_offset()?;
let Some(buffer) = self.payload.get_mut(offset..offset + SIZE_OF_MERKLE_ROOT) else {
Expand Down Expand Up @@ -361,10 +376,17 @@ impl ShredCode {
else {
return Err(Error::InvalidShredVariant);
};
Self::get_chained_merkle_root_offset(proof_size, resigned)
}

pub(super) fn get_chained_merkle_root_offset(
proof_size: u8,
resigned: bool,
) -> Result<usize, Error> {
Ok(Self::SIZE_OF_HEADERS + Self::capacity(proof_size, /*chained:*/ true, resigned)?)
}

fn chained_merkle_root(&self) -> Result<Hash, Error> {
pub(super) fn chained_merkle_root(&self) -> Result<Hash, Error> {
let offset = self.chained_merkle_root_offset()?;
self.payload
.get(offset..offset + SIZE_OF_MERKLE_ROOT)
Expand Down
7 changes: 7 additions & 0 deletions ledger/src/shred/shred_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ impl ShredCode {
}
}

pub(super) fn chained_merkle_root(&self) -> Result<Hash, Error> {
match self {
Self::Legacy(_) => Err(Error::InvalidShredType),
Self::Merkle(shred) => shred.chained_merkle_root(),
}
}

pub(super) fn merkle_root(&self) -> Result<Hash, Error> {
match self {
Self::Legacy(_) => Err(Error::InvalidShredType),
Expand Down
7 changes: 7 additions & 0 deletions ledger/src/shred/shred_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ impl ShredData {
}
}

pub(super) fn chained_merkle_root(&self) -> Result<Hash, Error> {
match self {
Self::Legacy(_) => Err(Error::InvalidShredType),
Self::Merkle(shred) => shred.chained_merkle_root(),
}
}

pub(super) fn merkle_root(&self) -> Result<Hash, Error> {
match self {
Self::Legacy(_) => Err(Error::InvalidShredType),
Expand Down

0 comments on commit a0bf2d6

Please sign in to comment.