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

Simplify blob sidecar availability checker #8840

Draft
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

tbenr
Copy link
Contributor

@tbenr tbenr commented Nov 20, 2024

blobs get from EL are marked as valid (trust assumption on EL)

TODO:

  • historical sync unit tests
  • gossip unit tests
  • rpc unit tests

fixes #8740

Documentation

  • I thought about documentation and added the doc-change-required label to this PR if updates are required.

Changelog

  • I thought about adding a changelog entry, and added one if I deemed necessary.

@@ -39,6 +39,9 @@ public class BlobSidecar
SignedBeaconBlockHeader,
SszBytes32Vector> {

private volatile boolean kzgAndInclusionProofValidated = false;
private volatile boolean signatureValidated = false;
Copy link
Contributor

@mehdi-aouadi mehdi-aouadi Nov 22, 2024

Choose a reason for hiding this comment

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

I find these validation steps a bit confusing and I'm wondering if we can't simply mark the blob sidecar as valid or not (merge them) or split the kzgAndInclusionProofValidated into two validation flags: kzgValidated and inclusionProofValidated. An and in a boolean variable name is red flag to me. Or do we really need this design for some reason I'm missing?!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the reason I put kzg and inclusion proof together and signatureValidation as a separate boolean is because we can perform kzg and inclusion proof validation just having the blob itself (you don't need anything else). For the signature validation you need a prevalidated signed block OR the state to get the pubkey from and do the signature check.

&& !blobSidecar
.getSignedBeaconBlockHeader()
.hashTreeRoot()
.equals(block.hashTreeRoot())) {
Copy link
Contributor

@mehdi-aouadi mehdi-aouadi Nov 22, 2024

Choose a reason for hiding this comment

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

Isn't this the same check done twice?!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

same check as which one?

Copy link
Contributor

Choose a reason for hiding this comment

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

I meant same as blobSidecar.isSignatureValidated()

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 but where am I doing this the second time?
I'm not sure this always checked. For instance the RPC lookups check blobs via BlobSidecarsByRootValidator.validate, which can only do kzg and inclusion proof.
So if we end up processing blobs coming from RPC source, we are not checking the block header in the blobSidecar (correct me if i'm wrong :) )

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh. I actually forgot to do the marking in BlobSidecarsByRangeListenerValidatingProxy

Copy link
Contributor Author

Choose a reason for hiding this comment

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

mmm maybe I can move those marking deeper in the stack and have them separated as you suggested

Copy link
Contributor

Choose a reason for hiding this comment

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

So if we end up processing blobs coming from RPC source, we are not checking the block header in the blobSidecar (correct me if i'm wrong :) )

Ok I see what you mean. One should keep in mind the whole flow to understand that...

@tbenr
Copy link
Contributor Author

tbenr commented Nov 22, 2024

since i forgot to do this marking i think the way I did it is a bit error prone. I'll change it.

@zilm13
Copy link
Contributor

zilm13 commented Nov 24, 2024

I will join Mehdi feedback:

  • if some validation was not performed I expect that we want to run it now
  • if it means that it was actually performed but failed it's confusing
  • I'm not sure on extending base BlobSidecar class, maybe better make some wrapper? It would be cleaner.
  • I'm happy with split kzg+inclusion / signature

@tbenr tbenr force-pushed the simplify-BlobSidecarAvailabilityChecker branch 3 times, most recently from 0cfe5bb to 39ecb99 Compare November 26, 2024 14:43
@tbenr tbenr force-pushed the simplify-BlobSidecarAvailabilityChecker branch from 39ecb99 to e3a2ee7 Compare December 9, 2024 16:37
Copy link
Contributor

@zilm13 zilm13 left a comment

Choose a reason for hiding this comment

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

Have not checked tests, yet (starting)

.hashTreeRoot()
.equals(block.hashTreeRoot());

if (signedHeaderMatchesBlock) {
Copy link
Contributor

Choose a reason for hiding this comment

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

it's a bit dirty, "side-effect", I'd just mark it in separate cycle after throw. Or even better mark it first and then boolean = allmatch(isSignatureValidated).

@@ -402,20 +400,30 @@ private void validateBlobSidecars(final SignedBeaconBlock block) {
final List<BlobSidecar> blobSidecars =
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe validateBlobSidecarsBlockSignature as it's the only thing we are checking here? The reason why I'm so meticulous here is because we don't even check we have all required blobSidecars here (I guess it's done in other place)

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 think you're right here. We rely on availability checker to verify the completeness. Need to think about if we want to continue exposing the check from the manager or do it here if it is the only place we need it.

}

public void markKzgAsValidated() {
kzgValidated = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

Still some uncertainty in this approach. Original container is immutable, this structure is mutable for these fields. Plus we add fields which are not used in equals, changes purpose etc. So (I'm not sure) I'd think on

  1. wrapper/keep as is
  2. immutable/mutable

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In my idea, due to the fact that the container is immutable, than we can safely have these additional flags.
So it is intentional that this fields are not part of the equality and the object must behave as these flags are not here at all. We can discuss it

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, just to check you are confident on it. Will not oppose.

blobSidecar.markKzgAsValidated();
}

return result;
Copy link
Contributor

Choose a reason for hiding this comment

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

For this and further check implementations. If check was failed we have a chance to run it twice (if called again). So may worth separate checkIsPerformed, checkIsPassed flags.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is true but I just wanted to keep it simple.
An option would be to have the flags as Optional.

But at the end I don't think it is really relevant because we discard the invalid blobs immediately (ie via gossip\rpc) so I don't think that we ever risk to validate an invalid one twice.

Copy link
Contributor

Choose a reason for hiding this comment

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

Didn't think about discard, looks reasonable, but I'd add some info somewhere for clarity. I don't know, javadoc to isKzgValidated maybe.

// there are no available blobs so far, but we are outside the availability window. We can
// skip additional checks
return Optional.of(BlobSidecarsAndValidationResult.NOT_REQUIRED);
for (final BlobSidecar blobSidecar : blobSidecars) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we put this check in some helper and reuse here and in HistoricalBatchFetcher.java

final SlotAndBlockRoot slotAndBlockRoot = blockBlobSidecarsTracker.getSlotAndBlockRoot();

final MiscHelpers miscHelpers = spec.atSlot(slotAndBlockRoot.getSlot()).miscHelpers();
private BlobSidecarsAndValidationResult validateCompletedBlobSidecars() {
Copy link
Contributor

Choose a reason for hiding this comment

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

where do we check that we have all blobSidecars for the number of commitments, I miss it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeh I was thinking that I've been too aggressive by removing the completeness check (which is also needed for historical sync). It's a cheap check and we should not rely on blobs tracker which rely only on blob indices to determine completeness. In general it is better that this class takes all it's responsibilities.

Copy link
Contributor Author

@tbenr tbenr Dec 10, 2024

Choose a reason for hiding this comment

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

well.. checked again and in theory what BlockBlobSidecarsTracker is doing should be good enough. 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

ok, I see, so it will fail by timeout. I'd add some comment for transparency.

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.

Simplify blobSidecar availability checker
3 participants