-
Notifications
You must be signed in to change notification settings - Fork 291
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
base: master
Are you sure you want to change the base?
Simplify blob sidecar availability checker #8840
Conversation
...ence-tests/src/referenceTest/java/tech/pegasys/teku/reference/ManualReferenceTestRunner.java
Outdated
Show resolved
Hide resolved
@@ -39,6 +39,9 @@ public class BlobSidecar | |||
SignedBeaconBlockHeader, | |||
SszBytes32Vector> { | |||
|
|||
private volatile boolean kzgAndInclusionProofValidated = false; | |||
private volatile boolean signatureValidated = false; |
There was a problem hiding this comment.
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?!
There was a problem hiding this comment.
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())) { |
There was a problem hiding this comment.
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?!
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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()
There was a problem hiding this comment.
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 :) )
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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...
since i forgot to do this marking i think the way I did it is a bit error prone. I'll change it. |
I will join Mehdi feedback:
|
0cfe5bb
to
39ecb99
Compare
39ecb99
to
e3a2ee7
Compare
There was a problem hiding this 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) { |
There was a problem hiding this comment.
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 = |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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
- wrapper/keep as is
- immutable/mutable
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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() { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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. 🤔
There was a problem hiding this comment.
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.
blobs get from EL are marked as valid (trust assumption on EL)
TODO:
fixes #8740
Documentation
doc-change-required
label to this PR if updates are required.Changelog