Skip to content

Commit 038a8c3

Browse files
committed
suggestion for isDataAvailable, stinky
1 parent 9bae8a2 commit 038a8c3

File tree

4 files changed

+66
-30
lines changed

4 files changed

+66
-30
lines changed

ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/MiscHelpers.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import com.google.common.primitives.UnsignedBytes;
2323
import it.unimi.dsi.fastutil.ints.IntList;
24+
import java.util.Collection;
2425
import java.util.List;
2526
import java.util.Optional;
2627
import java.util.stream.IntStream;
@@ -344,10 +345,19 @@ public boolean isExecutionEnabled(final BeaconState genericState, final BeaconBl
344345
}
345346

346347
/**
347-
* Performs data availability check (just KZG validation) assuming blobSidecar content (slot,
348-
* parent root, commitments) have been previously matched against the block
348+
* Performs data availability check for blobSidecars against block, assumes {@link
349+
* #verifyKzgProofBlobsBatch(List)} and {@link #validateBlobSidecarsAgainstBlock(List,
350+
* BeaconBlock, List)} were already performed
349351
*/
350-
public boolean isDataAvailable(final List<BlobSidecar> blobSidecars) {
352+
public boolean isDataAvailable(
353+
final BeaconBlock block, final Collection<BlobSidecar> verifiedBlobSidecars) {
354+
return false;
355+
}
356+
/**
357+
* Performs KZG validation assuming blobSidecar content (slot, parent root, commitments) have been
358+
* previously matched against the block
359+
*/
360+
public boolean verifyKzgProofBlobsBatch(final List<BlobSidecar> blobSidecars) {
351361
return false;
352362
}
353363

ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/deneb/blobs/BlobSidecarsAvailabilityChecker.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@ public BlobSidecarsAndValidationResult validateImmediately(
5757

5858
SafeFuture<BlobSidecarsAndValidationResult> getAvailabilityCheckResult();
5959

60-
/** Only perform the {@link MiscHelpersDeneb#isDataAvailable} check */
60+
/** Only perform the {@link MiscHelpersDeneb#verifyKzgProofBlobsBatch(List)} check */
6161
BlobSidecarsAndValidationResult validateImmediately(List<BlobSidecar> blobSidecars);
6262
}

ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/deneb/helpers/MiscHelpersDeneb.java

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717
import static tech.pegasys.teku.spec.config.SpecConfigDeneb.VERSIONED_HASH_VERSION_KZG;
1818

1919
import java.util.ArrayList;
20+
import java.util.Collection;
2021
import java.util.List;
2122
import java.util.Optional;
23+
import java.util.Set;
24+
import java.util.stream.Collectors;
25+
import java.util.stream.IntStream;
2226
import org.apache.tuweni.bytes.Bytes;
2327
import tech.pegasys.teku.infrastructure.crypto.Hash;
2428
import tech.pegasys.teku.infrastructure.ssz.SszList;
@@ -34,6 +38,7 @@
3438
import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock;
3539
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock;
3640
import tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.deneb.BeaconBlockBodyDeneb;
41+
import tech.pegasys.teku.spec.datastructures.networking.libp2p.rpc.BlobIdentifier;
3742
import tech.pegasys.teku.spec.logic.versions.capella.helpers.MiscHelpersCapella;
3843
import tech.pegasys.teku.spec.logic.versions.deneb.types.VersionedHash;
3944

@@ -58,15 +63,25 @@ private static KZG initKZG(final SpecConfigDeneb config) {
5863
return kzg;
5964
}
6065

61-
/**
62-
* <a
63-
* href="https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/fork-choice.md#is_data_available">is_data_available</a>
64-
*
65-
* <p>In Deneb we don't need to retrieve data, everything is already available via blob sidecars.
66-
*/
6766
@Override
68-
public boolean isDataAvailable(final List<BlobSidecar> blobSidecars) {
67+
public boolean isDataAvailable(
68+
final BeaconBlock block, final Collection<BlobSidecar> verifiedBlobSidecars) {
69+
final Set<BlobIdentifier> verifiedBlobIdentifiers =
70+
verifiedBlobSidecars.stream()
71+
.map(
72+
blobSidecar ->
73+
new BlobIdentifier(blobSidecar.getBlockRoot(), blobSidecar.getIndex()))
74+
.collect(Collectors.toSet());
75+
return IntStream.range(
76+
0, BeaconBlockBodyDeneb.required(block.getBody()).getBlobKzgCommitments().size())
77+
.mapToObj(index -> new BlobIdentifier(block.getRoot(), UInt64.valueOf(index)))
78+
.filter(blobIdentifier -> !verifiedBlobIdentifiers.contains(blobIdentifier))
79+
.findFirst()
80+
.isEmpty();
81+
}
6982

83+
@Override
84+
public boolean verifyKzgProofBlobsBatch(final List<BlobSidecar> blobSidecars) {
7085
final List<Bytes> blobs = new ArrayList<>();
7186
final List<KZGProof> proofs = new ArrayList<>();
7287
final List<KZGCommitment> kzgCommitments = new ArrayList<>();
@@ -93,7 +108,9 @@ public VersionedHash kzgCommitmentToVersionedHash(final KZGCommitment kzgCommitm
93108

94109
/**
95110
* The validation assumes that blockRoot and Slot are already matching. This is guaranteed by
96-
* BlobSidecarPool and BlockBlobSidecarsTracker
111+
* BlobSidecarPool and BlockBlobSidecarsTracker.
112+
*
113+
* <p>Doesn't require all blobs to be provided, verifies only provided blobs
97114
*
98115
* @param blobSidecars blob sidecars to validate
99116
* @param block block to validate blob sidecar against

ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/forkchoice/ForkChoiceBlobSidecarsAvailabilityChecker.java

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import com.google.common.base.Suppliers;
2020
import java.time.Duration;
2121
import java.util.ArrayList;
22-
import java.util.Collections;
22+
import java.util.Collection;
2323
import java.util.List;
2424
import java.util.NavigableMap;
2525
import java.util.Optional;
@@ -136,7 +136,7 @@ private BlobSidecarsAndValidationResult validateBatch(final List<BlobSidecar> bl
136136
miscHelpers.validateBlobSidecarsAgainstBlock(
137137
blobSidecars, block, kzgCommitmentsFromBlockSupplier.get());
138138

139-
if (!miscHelpers.isDataAvailable(blobSidecars)) {
139+
if (!miscHelpers.verifyKzgProofBlobsBatch(blobSidecars)) {
140140
return BlobSidecarsAndValidationResult.invalidResult(blobSidecars);
141141
}
142142
} catch (final Exception ex) {
@@ -196,7 +196,11 @@ && isBlockOutsideDataAvailabilityWindow()) {
196196
}
197197

198198
if (performCompleteValidation) {
199-
return Optional.of(result);
199+
if (result.isValid()) {
200+
return Optional.of(completeValidation());
201+
} else {
202+
return Optional.of(result);
203+
}
200204
}
201205

202206
// cache partially validated blobs
@@ -308,19 +312,25 @@ private BlobSidecarsAndValidationResult computeFinalValidationResult(
308312
.getBlobSidecars()
309313
.forEach(blobSidecar -> validatedBlobSidecars.put(blobSidecar.getIndex(), blobSidecar));
310314

311-
// let's create the final list of validated BlobSidecars making sure that indices and
312-
// final order are consistent
313-
final List<BlobSidecar> completeValidatedBlobSidecars = new ArrayList<>();
314-
validatedBlobSidecars.forEach(
315-
(index, blobSidecar) -> {
316-
checkState(
317-
index.equals(blobSidecar.getIndex())
318-
&& index.equals(UInt64.valueOf(completeValidatedBlobSidecars.size())),
319-
"Inconsistency detected during blob sidecar validation");
320-
completeValidatedBlobSidecars.add(blobSidecar);
321-
});
322-
323-
if (completeValidatedBlobSidecars.size() < kzgCommitmentsFromBlockSupplier.get().size()) {
315+
return completeValidation();
316+
}
317+
318+
private BlobSidecarsAndValidationResult completeValidation() {
319+
final BeaconBlock block = blockBlobSidecarsTracker.getBlock().orElseThrow();
320+
final MiscHelpers miscHelpers = spec.atSlot(block.getSlot()).miscHelpers();
321+
final Collection<BlobSidecar> maybeVerifiedBlobSidecars =
322+
validatedBlobSidecars
323+
.subMap(
324+
UInt64.ZERO,
325+
UInt64.valueOf(
326+
BeaconBlockBodyDeneb.required(
327+
blockBlobSidecarsTracker.getBlock().orElseThrow().getBody())
328+
.getBlobKzgCommitments()
329+
.size()))
330+
.values();
331+
final boolean isDataAvailable = miscHelpers.isDataAvailable(block, maybeVerifiedBlobSidecars);
332+
333+
if (!isDataAvailable) {
324334
// we haven't verified enough blobs to match the commitments present in the block
325335
// this should never happen in practice. If it does, is likely a bug and should be fixed.
326336
checkState(
@@ -332,8 +342,7 @@ private BlobSidecarsAndValidationResult computeFinalValidationResult(
332342
return BlobSidecarsAndValidationResult.NOT_REQUIRED;
333343
}
334344

335-
return BlobSidecarsAndValidationResult.validResult(
336-
Collections.unmodifiableList(completeValidatedBlobSidecars));
345+
return BlobSidecarsAndValidationResult.validResult(maybeVerifiedBlobSidecars.stream().toList());
337346
}
338347

339348
private boolean isBlockOutsideDataAvailabilityWindow() {

0 commit comments

Comments
 (0)