Skip to content

feat(state): Update Proposal with BlobID#7

Merged
alesforz merged 20 commits intoalesforz/feature/blobsfrom
alesforz/blobs/proposal
Mar 18, 2025
Merged

feat(state): Update Proposal with BlobID#7
alesforz merged 20 commits intoalesforz/feature/blobsfrom
alesforz/blobs/proposal

Conversation

@alesforz
Copy link
Owner

@alesforz alesforz commented Mar 14, 2025

Part of the work of berachain#26.

Context

A Proposal represents a block proposal that peers vote on during consensus. To be valid, it must be signed by the correct proposer for the given height and round.

A Proposal includes a BlockID, which uniquely identifies the proposed block. This BlockID contains the Merkle root hash of the block’s parts, ensuring integrity as the block is split and gossiped across the network.

Since blocks can now have an associated blob, we introduce a unique identifier for the blob in the Proposal struct. This allows peers to correctly associate a blob with its corresponding block during gossip. Additionally, because the Proposal is signed, this prevents malicious actors from altering or replacing the blob linked to a specific block.

Changes

This PR extends the Proposal struct and its methods with a BlobID field.

Alessandro Sforzin added 8 commits March 14, 2025 13:25
Regenerated the proto files as well.
Moved the proto definition of `BlobID` to the `types.proto` file to fix an
import cycle.
Since `BlobID` is not used in the consensus logic yet, this change is harmless.
However, it allows us to keep this PR focused solely on `Proposal`-related
changes.

In a future PR, we’ll handle the proper creation of `BlobID` by implementing
blob splitting into multiple parts.

Additionally, this PR includes a refactor for improved readability.
Alessandro Sforzin added 8 commits March 17, 2025 11:26
The `Proposal` sub-test was using an incorrect hex string to check the test's
results.
The string changed because we added the `BlobID` field to the `Proposal` type,
thus changing its encoding to protobuf.

Also rearrenged the code for better readability.
It was using an incorrect hex string to check the test's results.
The string changed because we added the `BlobID` field to the `Proposal` type,
thus changing its encoding to protobuf.

Also rearrenged the code for better readability.
The sub-tests "Proposal Request", "Proposal Response", and "Proposal Response
with error" were was using an incorrect hex string to check the test's results.

The string changed because we added the `BlobID` field to the `Proposal` type,
thus changing its encoding to protobuf.

Also rearrenged the code for better readability.
@alesforz
Copy link
Owner Author

The linter is failing, but that's not a real problem.
It's complaining about not using the blob object, but in the next PR(s) the code will use it.

@alesforz alesforz marked this pull request as ready for review March 17, 2025 14:04
p.POLRound = pp.PolRound // FIXME: names do not match
p.Timestamp = pp.Timestamp
p.Signature = pp.Signature
blobID, err := BlobIDFromProto(&pp.BlobID)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same as above, should we be checking if it is nil (maybe the check is performed inside BlobIDFromProto? ) ?

Copy link
Owner Author

Choose a reason for hiding this comment

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

yes, BlobIDFromProto checks if the given argument is nil and returns an error if it is.

Copy link
Collaborator

Choose a reason for hiding this comment

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

But can we not have a valid scenario where the blobID is nil (no blob in this proposal) and therefore it is ok that this is nil ? It should just be properly marshalled somehow.

Copy link
Owner Author

Choose a reason for hiding this comment

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

The BlobID field in the Proposal struct is a concrete type, not a pointer. Therefore, it can't be nil. Similarly, the BlobID field of the

the ToProto() and FromProto() methods of type BlobID return a concrete type, not a pointer. So I don't see how it could be set to nil.

@jmalicevic
Copy link
Collaborator

Update isProposalComplete() to account for the blob. We need to handle this carefully, as a missing blob could mean either that it hasn’t arrived yet or that the block simply doesn’t have one. We can distinguish between these cases by checking the Proposal: if BlobID is empty, the block has no blob. Otherwise, a blob exists, and we should wait for it.

If this is not supposed to be part of this PR, I would remove it from the description

Copy link
Collaborator

@melekes melekes left a comment

Choose a reason for hiding this comment

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

LGTM minus comments from Jasmina

@alesforz
Copy link
Owner Author

alesforz commented Mar 18, 2025

Update isProposalComplete() to account for the blob. We need to handle this carefully, as a missing blob could mean either that it hasn’t arrived yet or that the block simply doesn’t have one. We can distinguish between these cases by checking the Proposal: if BlobID is empty, the block has no blob. Otherwise, a blob exists, and we should wait for it.

If this is not supposed to be part of this PR, I would remove it from the description

I was thinking whether to include this change or not in this PR 🤔
It can fit here, but I also see it as part of the PR dealing with consensus rounds updates.

@alesforz alesforz requested review from jmalicevic and melekes March 18, 2025 08:13
Alessandro Sforzin added 2 commits March 18, 2025 09:53
Rationale: If a block has an associated blob, we set the `BlobID` in `Proposal`
after returning from `PrepareProposal()`, causing the `IsNil()` check to
return false. If the block does not have a blob, the `BlobID` field in
`Proposal` will remain its zero value, making `IsNil()` return true.

If a blob is present, `cs.ProposalBlob.IsNil()` will always return true until
`cs.ProposalBlob` is assigned a non-empty `[]byte` slice. This assignment
happens only after we have received all the blob parts and we have successfully
reconstructed the blob.
@alesforz
Copy link
Owner Author

alesforz commented Mar 18, 2025

Update isProposalComplete() to account for the blob. We need to handle this carefully, as a missing blob could mean either that it hasn’t arrived yet or that the block simply doesn’t have one. We can distinguish between these cases by checking the Proposal: if BlobID is empty, the block has no blob. Otherwise, a blob exists, and we should wait for it.

If this is not supposed to be part of this PR, I would remove it from the description

I was thinking whether to include this change or not in this PR 🤔 It can fit here, but I also see it as part of the PR dealing with consensus rounds updates.

Update, I pushed the change in this PR. See the last commit.

// wait for the blob before marking the proposal as complete.
if !cs.Proposal.BlobID.IsNil() {
return !cs.ProposalBlob.IsNil()
}
Copy link
Owner Author

Choose a reason for hiding this comment

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

Rationale: If a block has an associated blob, we set the BlobID in Proposal
after returning from PrepareProposal(), causing the IsNil() check to
return false. If the block does not have a blob, the BlobID field in
Proposal will remain its zero value, making IsNil() return true.

If a blob is present, cs.ProposalBlob.IsNil() will always return true until
cs.ProposalBlob is assigned a non-empty []byte slice. This assignment
happens only after we have received all the blob parts and we have successfully
reconstructed the blob.

@alesforz alesforz merged commit b5e984e into alesforz/feature/blobs Mar 18, 2025
18 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants