Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package tech.pegasys.teku.spec.util;

import static com.google.common.base.Preconditions.checkState;
import static ethereum.ckzg4844.CKZG4844JNI.BYTES_PER_CELL;
import static java.util.stream.Collectors.toList;
import static tech.pegasys.teku.ethereum.pow.api.DepositConstants.DEPOSIT_CONTRACT_TREE_DEPTH;
import static tech.pegasys.teku.infrastructure.unsigned.UInt64.ZERO;
Expand Down Expand Up @@ -77,6 +78,7 @@
import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszPrimitiveVectorSchema;
import tech.pegasys.teku.infrastructure.ssz.schema.collections.SszUInt64ListSchema;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.kzg.KZGCell;
import tech.pegasys.teku.kzg.KZGCommitment;
import tech.pegasys.teku.kzg.KZGProof;
import tech.pegasys.teku.spec.Spec;
Expand All @@ -92,6 +94,12 @@
import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSchema;
import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSidecar;
import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSidecarSchema;
import tech.pegasys.teku.spec.datastructures.blobs.versions.fulu.Cell;
import tech.pegasys.teku.spec.datastructures.blobs.versions.fulu.CellSchema;
import tech.pegasys.teku.spec.datastructures.blobs.versions.fulu.DataColumn;
import tech.pegasys.teku.spec.datastructures.blobs.versions.fulu.DataColumnSchema;
import tech.pegasys.teku.spec.datastructures.blobs.versions.fulu.DataColumnSidecar;
import tech.pegasys.teku.spec.datastructures.blobs.versions.fulu.DataColumnSidecarSchema;
import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock;
import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockAndState;
import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockHeader;
Expand Down Expand Up @@ -195,12 +203,14 @@
import tech.pegasys.teku.spec.executionlayer.PayloadBuildingAttributes;
import tech.pegasys.teku.spec.logic.versions.deneb.helpers.MiscHelpersDeneb;
import tech.pegasys.teku.spec.logic.versions.deneb.types.VersionedHash;
import tech.pegasys.teku.spec.logic.versions.fulu.helpers.MiscHelpersFulu;
import tech.pegasys.teku.spec.schemas.SchemaDefinitions;
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsAltair;
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsBellatrix;
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsCapella;
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsDeneb;
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsElectra;
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsFulu;

public final class DataStructureUtil {

Expand Down Expand Up @@ -2551,6 +2561,131 @@ public BlobSidecar build() {
}
}

public class RandomSidecarBuilder {
private Optional<UInt64> index = Optional.empty();
private Optional<DataColumn> dataColumn = Optional.empty();
private Optional<List<KZGCommitment>> kzgCommitments = Optional.empty();
private Optional<List<KZGProof>> kzgProofs = Optional.empty();
private Optional<SignedBeaconBlockHeader> signedBeaconBlockHeader = Optional.empty();
private Optional<List<Bytes32>> kzgCommitmentsInclusionProof = Optional.empty();

public RandomSidecarBuilder index(final UInt64 index) {
this.index = Optional.of(index);
return this;
}

public RandomSidecarBuilder dataColumn(final DataColumn dataColumn) {
this.dataColumn = Optional.of(dataColumn);
return this;
}

public RandomSidecarBuilder kzgCommitments(final List<KZGCommitment> kzgCommitments) {
this.kzgCommitments = Optional.of(kzgCommitments);
return this;
}

public RandomSidecarBuilder kzgProofs(final List<KZGProof> kzgProofs) {
this.kzgProofs = Optional.of(kzgProofs);
return this;
}

public RandomSidecarBuilder signedBeaconBlockHeader(
final SignedBeaconBlockHeader signedBeaconBlockHeader) {
this.signedBeaconBlockHeader = Optional.of(signedBeaconBlockHeader);
return this;
}

public RandomSidecarBuilder kzgCommitmentsInclusionProof(
final List<Bytes32> kzgCommitmentsInclusionProof) {
this.kzgCommitmentsInclusionProof = Optional.of(kzgCommitmentsInclusionProof);
return this;
}

public DataColumnSidecar build() {
final SignedBeaconBlockHeader signedBlockHeader =
signedBeaconBlockHeader.orElseGet(DataStructureUtil.this::randomSignedBeaconBlockHeader);
final DataColumnSidecarSchema dataColumnSidecarSchema =
getFuluSchemaDefinitions(signedBlockHeader.getMessage().getSlot())
.getDataColumnSidecarSchema();
final int numberOfProofs =
kzgProofs
.map(List::size)
.or(() -> kzgCommitments.map(List::size))
.orElseGet(DataStructureUtil.this::randomNumberOfBlobsPerBlock);

return dataColumnSidecarSchema.create(
index.orElseGet(DataStructureUtil.this::randomBlobSidecarIndex),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

it should be 0 to 127 (inclusive), number of blobs looks too small. I think we have getNumberOfColumns() here

dataColumn.orElseGet(
() -> randomDataColumn(signedBlockHeader.getMessage().getSlot(), numberOfProofs)),
kzgCommitments.orElseGet(
() ->
IntStream.range(0, numberOfProofs)
.mapToObj(__ -> randomKZGCommitment())
.toList()),
kzgProofs.orElseGet(
() -> IntStream.range(0, numberOfProofs).mapToObj(__ -> randomKZGProof()).toList()),
signedBlockHeader,
kzgCommitmentsInclusionProof.orElseGet(
() ->
IntStream.range(
0,
dataColumnSidecarSchema
.getKzgCommitmentsInclusionProofSchema()
.getLength())
.mapToObj(__ -> randomBytes32())
.toList()));
}
}

public DataColumn randomDataColumn(final UInt64 slot, final int blobs) {
final DataColumnSchema dataColumnSchema = getFuluSchemaDefinitions(slot).getDataColumnSchema();
List<Cell> list = IntStream.range(0, blobs).mapToObj(__ -> randomCell(slot)).toList();
return dataColumnSchema.create(list);
}

public Cell randomCell(final UInt64 slot) {
final CellSchema cellSchema = getFuluSchemaDefinitions(slot).getCellSchema();
return cellSchema.create(randomBytes(cellSchema.getLength()));
}

public KZGCell randomKZGCell() {
return new KZGCell(randomBytes(BYTES_PER_CELL));
}

public DataColumnSidecar randomDataColumnSidecar() {
return new RandomSidecarBuilder().build();
}

public DataColumnSidecar randomDataColumnSidecar(
final SignedBeaconBlockHeader header, final UInt64 index) {
return new RandomSidecarBuilder().signedBeaconBlockHeader(header).index(index).build();
}

public DataColumnSidecar randomDataColumnSidecarWithInclusionProof(
final SignedBeaconBlock signedBeaconBlock, final UInt64 index) {
final MiscHelpersFulu miscHelpersFulu =
MiscHelpersFulu.required(spec.getGenesisSpec().miscHelpers());
final List<KZGCommitment> kzgCommitments =
signedBeaconBlock
.getMessage()
.getBody()
.getOptionalBlobKzgCommitments()
.orElseThrow()
.asList()
.stream()
.map(SszKZGCommitment::getKZGCommitment)
.toList();
final List<Bytes32> inclusionProof =
miscHelpersFulu.computeDataColumnKzgCommitmentsInclusionProof(
signedBeaconBlock.getBeaconBlock().orElseThrow().getBody());
return new RandomSidecarBuilder()
.signedBeaconBlockHeader(signedBeaconBlock.asHeader())
.kzgCommitments(kzgCommitments)
.kzgCommitmentsInclusionProof(inclusionProof)
.index(index)
.build();
}

public List<Bytes32> randomKzgCommitmentInclusionProof() {
final int depth =
SpecConfigDeneb.required(spec.forMilestone(SpecMilestone.DENEB).getConfig())
Expand Down Expand Up @@ -2712,6 +2847,10 @@ private SchemaDefinitionsElectra getElectraSchemaDefinitions(final UInt64 slot)
return SchemaDefinitionsElectra.required(spec.atSlot(slot).getSchemaDefinitions());
}

private SchemaDefinitionsFulu getFuluSchemaDefinitions(final UInt64 slot) {
return SchemaDefinitionsFulu.required(spec.atSlot(slot).getSchemaDefinitions());
}

int getEpochsPerEth1VotingPeriod() {
return getConstant(SpecConfig::getEpochsPerEth1VotingPeriod);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright Consensys Software Inc., 2024
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

package tech.pegasys.teku.statetransition.datacolumns;

import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.spec.config.SpecConfigFulu;

public interface MinCustodyPeriodSlotCalculator {

static MinCustodyPeriodSlotCalculator createFromSpec(final Spec spec) {
return currentSlot -> {
final UInt64 currentEpoch = spec.computeEpochAtSlot(currentSlot);
final int custodyPeriodEpochs =
spec.getSpecConfig(currentEpoch)
.toVersionFulu()
.map(SpecConfigFulu::getMinEpochsForDataColumnSidecarsRequests)
.orElse(0);
if (custodyPeriodEpochs == 0) {
return currentSlot;
} else {
final UInt64 minCustodyEpoch = currentEpoch.minusMinZero(custodyPeriodEpochs);
return spec.computeStartSlotAtEpoch(minCustodyEpoch);
}
};
}

UInt64 getMinCustodyPeriodSlot(UInt64 currentSlot);
}
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@
import tech.pegasys.teku.storage.api.CombinedStorageChannel;
import tech.pegasys.teku.storage.api.Eth1DepositStorageChannel;
import tech.pegasys.teku.storage.api.FinalizedCheckpointChannel;
import tech.pegasys.teku.storage.api.SidecarUpdateChannel;
import tech.pegasys.teku.storage.api.StorageQueryChannel;
import tech.pegasys.teku.storage.api.StorageUpdateChannel;
import tech.pegasys.teku.storage.api.VoteUpdateChannel;
Expand Down Expand Up @@ -455,6 +456,7 @@ protected SafeFuture<?> initialize() {
storageQueryChannel,
storageUpdateChannel,
voteUpdateChannel,
eventChannels.getPublisher(SidecarUpdateChannel.class, beaconAsyncRunner),
eventChannels.getPublisher(FinalizedCheckpointChannel.class, beaconAsyncRunner),
coalescingChainHeadChannel,
validatorIsConnectedProvider,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import tech.pegasys.teku.spec.networks.Eth2Network;
import tech.pegasys.teku.storage.api.CombinedStorageChannel;
import tech.pegasys.teku.storage.api.Eth1DepositStorageChannel;
import tech.pegasys.teku.storage.api.SidecarUpdateChannel;
import tech.pegasys.teku.storage.api.VoteUpdateChannel;
import tech.pegasys.teku.storage.archive.BlobSidecarsArchiver;
import tech.pegasys.teku.storage.archive.filesystem.FileSystemBlobSidecarsArchiver;
Expand Down Expand Up @@ -218,7 +219,8 @@ protected SafeFuture<?> doStart() {
eventChannels
.subscribe(Eth1DepositStorageChannel.class, depositStorage)
.subscribe(Eth1EventsChannel.class, depositStorage)
.subscribe(VoteUpdateChannel.class, batchingVoteUpdateChannel);
.subscribe(VoteUpdateChannel.class, batchingVoteUpdateChannel)
.subscribe(SidecarUpdateChannel.class, chainStorage);
})
.thenCompose(
__ ->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright Consensys Software Inc., 2022
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

package tech.pegasys.teku.storage.api;

import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.infrastructure.events.ChannelInterface;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.datastructures.blobs.versions.fulu.DataColumnSidecar;

public interface SidecarUpdateChannel extends ChannelInterface {

// TODO: as it's pushed separately from sidecars, an eventual consistency could occur.
// Clarify that it's safe
SafeFuture<Void> onFirstCustodyIncompleteSlot(UInt64 slot);

SafeFuture<Void> onFirstSamplerIncompleteSlot(UInt64 slot);

SafeFuture<Void> onNewSidecar(DataColumnSidecar sidecar);

// TODO: Make a dedicated pruner instead
SafeFuture<Void> onSidecarsAvailabilitySlot(UInt64 earliestSlotRequired);
Comment thread
lucassaldanha marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@
import tech.pegasys.teku.infrastructure.events.ChannelInterface;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSidecar;
import tech.pegasys.teku.spec.datastructures.blobs.versions.fulu.DataColumnSidecar;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState;
import tech.pegasys.teku.spec.datastructures.blocks.SlotAndBlockRoot;
import tech.pegasys.teku.spec.datastructures.blocks.StateAndBlockSummary;
import tech.pegasys.teku.spec.datastructures.state.Checkpoint;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
import tech.pegasys.teku.spec.datastructures.util.DataColumnSlotAndIdentifier;
import tech.pegasys.teku.spec.datastructures.util.SlotAndBlockRootAndBlobIndex;

public interface StorageQueryChannel extends ChannelInterface {
Expand Down Expand Up @@ -114,4 +116,20 @@ SafeFuture<List<SlotAndBlockRootAndBlobIndex>> getBlobSidecarKeys(
SafeFuture<List<BlobSidecar>> getArchivedBlobSidecars(SlotAndBlockRoot slotAndBlockRoot);

SafeFuture<List<BlobSidecar>> getArchivedBlobSidecars(UInt64 slot);

SafeFuture<Optional<UInt64>> getFirstCustodyIncompleteSlot();

SafeFuture<Optional<UInt64>> getFirstSamplerIncompleteSlot();

SafeFuture<Optional<DataColumnSidecar>> getSidecar(DataColumnSlotAndIdentifier identifier);

SafeFuture<Optional<DataColumnSidecar>> getNonCanonicalSidecar(
DataColumnSlotAndIdentifier identifier);

SafeFuture<List<DataColumnSlotAndIdentifier>> getDataColumnIdentifiers(UInt64 slot);

SafeFuture<List<DataColumnSlotAndIdentifier>> getDataColumnIdentifiers(
UInt64 startSlot, UInt64 endSlot, UInt64 limit);

SafeFuture<Optional<UInt64>> getEarliestDataColumnSidecarSlot();
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class StorageUpdate {
private final Optional<Bytes32> optimisticTransitionBlockRoot;
private final Optional<Bytes32> latestCanonicalBlockRoot;
private final boolean blobSidecarsEnabled;
private final boolean sidecarsEnabled;
private final boolean isEmpty;

public StorageUpdate(
Expand All @@ -64,7 +65,8 @@ public StorageUpdate(
final boolean optimisticTransitionBlockRootSet,
final Optional<Bytes32> optimisticTransitionBlockRoot,
final Optional<Bytes32> latestCanonicalBlockRoot,
@NonUpdating final boolean blobSidecarsEnabled) {
@NonUpdating final boolean blobSidecarsEnabled,
@NonUpdating final boolean sidecarsEnabled) {
Comment on lines +68 to +69

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question the need for this annotation on a final

this.genesisTime = genesisTime;
this.finalizedChainData = finalizedChainData;
this.justifiedCheckpoint = justifiedCheckpoint;
Expand All @@ -79,6 +81,7 @@ public StorageUpdate(
this.optimisticTransitionBlockRoot = optimisticTransitionBlockRoot;
this.latestCanonicalBlockRoot = latestCanonicalBlockRoot;
this.blobSidecarsEnabled = blobSidecarsEnabled;
this.sidecarsEnabled = sidecarsEnabled;
checkArgument(
optimisticTransitionBlockRootSet || optimisticTransitionBlockRoot.isEmpty(),
"Can't have optimisticTransitionBlockRoot present but not set");
Expand Down Expand Up @@ -176,6 +179,10 @@ public boolean isBlobSidecarsEnabled() {
return blobSidecarsEnabled;
}

public boolean isSidecarsEnabled() {
return sidecarsEnabled;
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@interface NonUpdating {}
Expand Down
Loading