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

removes the merkle root from shreds binary #29427

Merged
merged 1 commit into from
Feb 15, 2023

Conversation

behzadnouri
Copy link
Contributor

@behzadnouri behzadnouri commented Dec 28, 2022

Problem

  • The merkle root is unnecessary encoded into shreds binary, reducing shreds capacity to store data.
  • The root is 32 bytes hash, but since the merkle root is truncated, the signature is on the truncated 20 bytes.

Summary of Changes

#29445 makes it unnecessary to embed merkle roots into shreds binary. This commit removes the merkle root from shreds binary.

This adds 20 bytes to shreds capacity to store more data.
Additionally since we no longer need to truncate the merkle root, the signature would be on the full 32 bytes of hash as opposed to the truncated one.

Also signature verification would now effectively verify merkle proof as well, so we no longer need to verify merkle proof in the sanitize implementation.

@behzadnouri behzadnouri force-pushed the rm-merkle-root branch 29 times, most recently from f639e75 to 49c523d Compare December 30, 2022 17:08
@behzadnouri behzadnouri changed the title removes merkle root from shred binary removes merkle root from shreds binary Dec 30, 2022
@behzadnouri behzadnouri force-pushed the rm-merkle-root branch 5 times, most recently from 6c1626f to 346be25 Compare January 5, 2023 17:18
jbiseda
jbiseda previously approved these changes Jan 7, 2023
Copy link
Contributor

@jbiseda jbiseda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

I think it may make it easier to read if you expose shred::OFFSET_OF_SHRED_VARIANT and use that in place of SIZE_OF_SIGNATURE.

let index = self.erasure_shard_index()?;
let proof_offset = Self::proof_offset(proof_size)?;
let proof = get_merkle_proof(&self.payload, proof_offset, proof_size)?;
let node = get_merkle_node(&self.payload, SIZE_OF_SIGNATURE..proof_offset)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/SIZE_OF_SIGNATURE/OFFSET_OF_SHRED_VARIANT/ for clarity?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok(verify_merkle_proof(index, node, &self.merkle_branch()?))
fn merkle_node(&self) -> Result<Hash, Error> {
let proof_size = self.proof_size()?;
let offsets = SIZE_OF_SIGNATURE..Self::proof_offset(proof_size)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/SIZE_OF_SIGNATURE/OFFSET_OF_SHRED_VARIANT/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_merkle_root(shred, proof_size, index, offset)
let proof_offset = Self::proof_offset(proof_size).ok()?;
let proof = get_merkle_proof(shred, proof_offset, proof_size).ok()?;
let node = get_merkle_node(shred, SIZE_OF_SIGNATURE..proof_offset).ok()?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/SIZE_OF_SIGNATURE/OFFSET_OF_SHRED_VARIANT/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok(<&MerkleRoot>::try_from(root).unwrap())
// Where the merkle proof starts in the shred binary.
fn proof_offset(proof_size: u8) -> Result<usize, Error> {
Ok(Self::SIZE_OF_HEADERS + Self::capacity(proof_size)?)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/SIZE_OF_SIGNATURE/OFFSET_OF_SHRED_VARIANT/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a SIZE_OF_SIGNATURE here.

let index = self.erasure_shard_index()?;
let proof_offset = Self::proof_offset(proof_size)?;
let proof = get_merkle_proof(&self.payload, proof_offset, proof_size)?;
let node = get_merkle_node(&self.payload, SIZE_OF_SIGNATURE..proof_offset)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/SIZE_OF_SIGNATURE/OFFSET_OF_SHRED_VARIANT/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some(offset..offset + SIZE_OF_MERKLE_ROOT)
fn merkle_node(&self) -> Result<Hash, Error> {
let proof_size = self.proof_size()?;
let offsets = SIZE_OF_SIGNATURE..Self::proof_offset(proof_size)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/SIZE_OF_SIGNATURE/OFFSET_OF_SHRED_VARIANT/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_merkle_root(shred, proof_size, index, offset)
let proof_offset = Self::proof_offset(proof_size).ok()?;
let proof = get_merkle_proof(shred, proof_offset, proof_size).ok()?;
let node = get_merkle_node(shred, SIZE_OF_SIGNATURE..proof_offset).ok()?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/SIZE_OF_SIGNATURE/OFFSET_OF_SHRED_VARIANT/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.payload
.get(SIZE_OF_SIGNATURE..Self::SIZE_OF_HEADERS + data_buffer_size)
.get(SIZE_OF_SIGNATURE..proof_offset)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/SIZE_OF_SIGNATURE/OFFSET_OF_SHRED_VARIANT/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.payload
.get(Self::SIZE_OF_HEADERS..Self::SIZE_OF_HEADERS + shard_size)
.get(Self::SIZE_OF_HEADERS..proof_offset)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/SIZE_OF_SIGNATURE/OFFSET_OF_SHRED_VARIANT/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a SIZE_OF_SIGNATURE here.

@behzadnouri
Copy link
Contributor Author

I think it may make it easier to read if you expose shred::OFFSET_OF_SHRED_VARIANT and use that in place of SIZE_OF_SIGNATURE.

SIZE_OF_SIGNATURE.. indicates that we are skipping over the signature bytes, because only once we have the erasure coding shards and the merkle tree is constructed, we can sign the merkle root and attach the signature. So the signature bytes won't be included in either erasure coding or merkle tree construction and so are skipped over in all these offsets.
That is also consistent with merkle layout description in the comments which states that "The slice past signature and before merkle branch" is erasure coded or used in merkle tree construction:
https://github.com/solana-labs/solana/blob/8c212f59a/ledger/src/shred/merkle.rs#L52-L55
https://github.com/solana-labs/solana/blob/8c212f59a/ledger/src/shred/merkle.rs#L63-L65

I believe that skipping over signature bytes is better indicated in the code by SIZE_OF_SIGNATURE...
Changing this to OFFSET_OF_SHRED_VARIANT would be less clear why we start off the shred-variant offset.

@mergify mergify bot dismissed jbiseda’s stale review January 8, 2023 16:27

Pull request has been modified.

@jbiseda
Copy link
Contributor

jbiseda commented Jan 9, 2023

I believe that skipping over signature bytes is better indicated in the code by SIZE_OF_SIGNATURE... Changing this to OFFSET_OF_SHRED_VARIANT would be less clear why we start off the shred-variant offset.

Ok, I'm fine with SIZE_OF_SIGNATURE.

solana-labs#29445
makes it unnecessary to embed merkle roots into shreds binary. This
commit removes the merkle root from shreds binary.

This adds 20 bytes to shreds capacity to store more data.
Additionally since we no longer need to truncate the merkle root, the
signature would be on the full 32 bytes of hash as opposed to the
truncated one.

Also signature verification would now effectively verify merkle proof as
well, so we no longer need to verify merkle proof in the sanitize
implementation.
@behzadnouri behzadnouri merged commit cf0a149 into solana-labs:master Feb 15, 2023
@behzadnouri behzadnouri deleted the rm-merkle-root branch February 15, 2023 21:17
@behzadnouri behzadnouri added v1.15 (abandoned) The v1.15 branch has been abandoned and removed do-not-close Add this tag to exempt an issue/PR from being closed by the stalebot labels Feb 15, 2023
mergify bot pushed a commit that referenced this pull request Feb 15, 2023
#29445
makes it unnecessary to embed merkle roots into shreds binary. This
commit removes the merkle root from shreds binary.

This adds 20 bytes to shreds capacity to store more data.
Additionally since we no longer need to truncate the merkle root, the
signature would be on the full 32 bytes of hash as opposed to the
truncated one.

Also signature verification would now effectively verify merkle proof as
well, so we no longer need to verify merkle proof in the sanitize
implementation.

(cherry picked from commit cf0a149)
mergify bot added a commit that referenced this pull request Feb 15, 2023
#30344)

removes the merkle root from shreds binary (#29427)

#29445
makes it unnecessary to embed merkle roots into shreds binary. This
commit removes the merkle root from shreds binary.

This adds 20 bytes to shreds capacity to store more data.
Additionally since we no longer need to truncate the merkle root, the
signature would be on the full 32 bytes of hash as opposed to the
truncated one.

Also signature verification would now effectively verify merkle proof as
well, so we no longer need to verify merkle proof in the sanitize
implementation.

(cherry picked from commit cf0a149)

Co-authored-by: behzad nouri <[email protected]>
mergify bot pushed a commit that referenced this pull request Mar 6, 2023
#29445
makes it unnecessary to embed merkle roots into shreds binary. This
commit removes the merkle root from shreds binary.

This adds 20 bytes to shreds capacity to store more data.
Additionally since we no longer need to truncate the merkle root, the
signature would be on the full 32 bytes of hash as opposed to the
truncated one.

Also signature verification would now effectively verify merkle proof as
well, so we no longer need to verify merkle proof in the sanitize
implementation.

(cherry picked from commit cf0a149)

# Conflicts:
#	ledger/src/shred.rs
behzadnouri added a commit that referenced this pull request Mar 7, 2023
#30613)

* removes the merkle root from shreds binary (#29427)

#29445
makes it unnecessary to embed merkle roots into shreds binary. This
commit removes the merkle root from shreds binary.

This adds 20 bytes to shreds capacity to store more data.
Additionally since we no longer need to truncate the merkle root, the
signature would be on the full 32 bytes of hash as opposed to the
truncated one.

Also signature verification would now effectively verify merkle proof as
well, so we no longer need to verify merkle proof in the sanitize
implementation.

(cherry picked from commit cf0a149)

# Conflicts:
#	ledger/src/shred.rs

* resolves mergify merge conflicts

---------

Co-authored-by: behzad nouri <[email protected]>
nickfrosty pushed a commit to nickfrosty/solana that referenced this pull request Mar 12, 2023
solana-labs#29445
makes it unnecessary to embed merkle roots into shreds binary. This
commit removes the merkle root from shreds binary.

This adds 20 bytes to shreds capacity to store more data.
Additionally since we no longer need to truncate the merkle root, the
signature would be on the full 32 bytes of hash as opposed to the
truncated one.

Also signature verification would now effectively verify merkle proof as
well, so we no longer need to verify merkle proof in the sanitize
implementation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v1.15 (abandoned) The v1.15 branch has been abandoned
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants