Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into cleanup-todos
Browse files Browse the repository at this point in the history
  • Loading branch information
rolfyone committed Jan 23, 2025
2 parents d1b0b22 + 3b29505 commit 7386e4a
Show file tree
Hide file tree
Showing 13 changed files with 259 additions and 177 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -598,10 +598,8 @@ public void createAttestationData_shouldFailWhenHeadIsOptimistic() {
final UInt64 slot = spec.computeStartSlotAtEpoch(EPOCH).plus(ONE);
when(chainDataClient.getCurrentSlot()).thenReturn(slot);

final BeaconState state = createStateWithActiveValidators(epochStartSlot);
final SignedBeaconBlock block =
dataStructureUtil.randomSignedBeaconBlock(state.getSlot(), state);
final SignedBlockAndState blockAndState = new SignedBlockAndState(block, state);
final SignedBlockAndState blockAndState =
dataStructureUtil.randomSignedBlockAndState(epochStartSlot);

final SafeFuture<Optional<SignedBlockAndState>> blockAndStateResult =
completedFuture(Optional.of(blockAndState));
Expand All @@ -624,10 +622,9 @@ public void createAttestationData_shouldCreateAttestation() {
final UInt64 slot = spec.computeStartSlotAtEpoch(EPOCH).plus(ONE);
when(chainDataClient.getCurrentSlot()).thenReturn(slot);

final BeaconState state = createStateWithActiveValidators(epochStartSlot);
final SignedBeaconBlock block =
dataStructureUtil.randomSignedBeaconBlock(state.getSlot(), state);
final SignedBlockAndState blockAndState = new SignedBlockAndState(block, state);
dataStructureUtil.randomBlockAndState(epochStartSlot);
final SignedBlockAndState blockAndState =
dataStructureUtil.randomSignedBlockAndState(epochStartSlot);

final SafeFuture<Optional<SignedBlockAndState>> blockAndStateResult =
completedFuture(Optional.of(blockAndState));
Expand All @@ -646,7 +643,10 @@ public void createAttestationData_shouldCreateAttestation() {
assertThat(attestationData)
.isEqualTo(
spec.getGenericAttestationData(
slot, state, block.getMessage(), UInt64.valueOf(committeeIndex)));
slot,
blockAndState.getState(),
blockAndState.getBlock().getMessage(),
UInt64.valueOf(committeeIndex)));
assertThat(attestationData.getSlot()).isEqualTo(slot);
final InOrder inOrder = inOrder(forkChoiceTrigger, chainDataClient);

Expand Down Expand Up @@ -674,11 +674,10 @@ public void createAttestationData_shouldUseCorrectSourceWhenEpochTransitionRequi
// Slot is from before the current epoch, so we need to ensure we process the epoch transition
final UInt64 blockSlot = slot.minus(1);

final BeaconState wrongState = createStateWithActiveValidators(blockSlot);
final BeaconState rightState = createStateWithActiveValidators(slot);
final SignedBeaconBlock block =
dataStructureUtil.randomSignedBeaconBlock(wrongState.getSlot(), wrongState);
final SignedBlockAndState blockAndState = new SignedBlockAndState(block, wrongState);
final SignedBlockAndState blockAndState =
dataStructureUtil.randomSignedBlockAndState(blockSlot);
final SignedBeaconBlock block = blockAndState.getBlock();

final SafeFuture<Optional<SignedBlockAndState>> blockAndStateResult =
completedFuture(Optional.of(blockAndState));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,13 @@ public StateSelector genesisSelector() {
@Override
public StateSelector finalizedSelector() {
return () ->
SafeFuture.completedFuture(
client
.getLatestFinalized()
.map(
finalized ->
addMetaData(
finalized.getState(),
// The finalized checkpoint may change because of optimistically
// imported blocks at the head and if the head isn't optimistic, the
// finalized block can't be optimistic.
client.isChainHeadOptimistic(),
true,
true)));
client
.getBestFinalizedState()
.thenApply(
maybeFinalized ->
maybeFinalized.map(
finalized ->
addMetaData(finalized, client.isChainHeadOptimistic(), true, true)));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockHeader;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState;
import tech.pegasys.teku.spec.datastructures.metadata.StateAndMetaData;
import tech.pegasys.teku.spec.datastructures.state.AnchorPoint;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
import tech.pegasys.teku.spec.util.DataStructureUtil;
import tech.pegasys.teku.storage.api.StorageQueryChannel;
Expand Down Expand Up @@ -66,8 +65,7 @@ public void headSelector_shouldGetBestState() {

@Test
public void finalizedSelector_shouldGetFinalizedState() {
when(client.getLatestFinalized())
.thenReturn(Optional.of(AnchorPoint.fromInitialState(spec, state)));
when(client.getBestFinalizedState()).thenReturn(SafeFuture.completedFuture(Optional.of(state)));
Optional<StateAndMetaData> result = safeJoin(factory.finalizedSelector().getState());
assertThat(result).contains(withMetaData(state, true));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,20 @@ public class StateAndBlockSummary implements BeaconBlockSummary {
protected StateAndBlockSummary(final BeaconBlockSummary blockSummary, final BeaconState state) {
checkNotNull(blockSummary);
checkNotNull(state);
checkArgument(
blockSummary.getStateRoot().equals(state.hashTreeRoot()),
"Block state root must match the supplied state");
final Bytes32 latestBlockHeaderBodyRoot = state.getLatestBlockHeader().getBodyRoot();
// if the state slot is 0, we're either at genesis or testing
if (!state.getSlot().isZero()) {
// This check would allow a state to have an empty slot, and still be a valid block and state.
checkArgument(
latestBlockHeaderBodyRoot.equals(blockSummary.getBodyRoot()),
String.format(
"Latest Block body root %s in state at slot %s must match the block summary root. "
+ "Block slot %s, block body root %s",
latestBlockHeaderBodyRoot,
state.getSlot(),
blockSummary.getSlot(),
blockSummary.getBodyRoot()));
}
this.blockSummary = blockSummary;
this.state = state;
}
Expand Down Expand Up @@ -128,7 +139,10 @@ public int hashCode() {

@Override
public String toString() {
return MoreObjects.toStringHelper(this).add("blockSummary", blockSummary).toString();
return MoreObjects.toStringHelper(this)
.add("blockSummary", blockSummary)
.add("state", state)
.toString();
}

private Optional<ExecutionPayloadHeader> getLatestExecutionPayloadHeader() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
/**
* Represents an "anchor" - a trusted, finalized (block, state, checkpoint) tuple from which we can
* sync.
*
* <p>NOTE: Anchor point is a teku concept. <br>
* - state needs to be the anchor_state as used in fork choice<br>
* - checkpoint is an actual checkpoint as defined in fork choice, is the first slot of epoch<br>
* - blockSummary is the block from the finalized anchor state
*/
public class AnchorPoint extends StateAndBlockSummary {
private final Spec spec;
Expand Down Expand Up @@ -66,14 +71,6 @@ public static AnchorPoint create(
return new AnchorPoint(spec, checkpoint, state, blockSummary);
}

public static AnchorPoint create(
final Spec spec,
final Checkpoint checkpoint,
final SignedBeaconBlock block,
final BeaconState state) {
return new AnchorPoint(spec, checkpoint, state, block);
}

public static AnchorPoint create(
final Spec spec, final Checkpoint checkpoint, final SignedBlockAndState blockAndState) {
return new AnchorPoint(spec, checkpoint, blockAndState.getState(), blockAndState.getBlock());
Expand Down Expand Up @@ -107,16 +104,16 @@ public static AnchorPoint fromInitialState(final Spec spec, final BeaconState st
}
}

private static boolean isGenesisState(final BeaconState state) {
return state.getSlot().equals(SpecConfig.GENESIS_SLOT);
}

public static AnchorPoint fromInitialBlockAndState(
final Spec spec, final SignedBlockAndState blockAndState) {
return fromInitialBlockAndState(spec, blockAndState.getBlock(), blockAndState.getState());
}

public static AnchorPoint fromInitialBlockAndState(
private static boolean isGenesisState(final BeaconState state) {
return state.getSlot().equals(SpecConfig.GENESIS_SLOT);
}

private static AnchorPoint fromInitialBlockAndState(
final Spec spec, final SignedBeaconBlock block, final BeaconState state) {
checkArgument(
Objects.equals(block.getStateRoot(), state.hashTreeRoot()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public UInt64 getLatestFinalizedBlockSlot() {
public AnchorPoint getLatestFinalized() {
final SignedBeaconBlock block = getSignedBlock(finalizedCheckpoint.getRoot());
final BeaconState state = getBlockState(finalizedCheckpoint.getRoot());
return AnchorPoint.create(spec, finalizedCheckpoint, block, state);
return AnchorPoint.create(spec, finalizedCheckpoint, state, Optional.of(block));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import tech.pegasys.teku.spec.config.SpecConfig;
import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.Blob;
import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock;
import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlockHeader;
import tech.pegasys.teku.spec.datastructures.blocks.Eth1Data;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState;
Expand Down Expand Up @@ -223,11 +224,14 @@ public SafeFuture<SignedBlockAndState> createNewBlockSkippingStateTransition(
blockBody);

// Sign block and set block signature
BLSSignature blockSignature = signer.signBlock(block, state.getForkInfo()).join();
final BLSSignature blockSignature =
signer.signBlock(block, state.getForkInfo()).join();

final SignedBeaconBlock signedBlock =
SignedBeaconBlock.create(spec, block, blockSignature);
return new SignedBlockAndState(signedBlock, blockSlotState);
final BeaconState updatedState =
state.updated(w -> w.setLatestBlockHeader(BeaconBlockHeader.fromBlock(block)));
return new SignedBlockAndState(signedBlock, updatedState);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,10 @@ public List<SignedBlockAndState> randomSignedBlockAndStateSequence(
final Bytes32 stateRoot = state.hashTreeRoot();
final SignedBeaconBlock block =
signedBlock(randomBeaconBlock(nextSlot, parentRoot, stateRoot, full));
blocks.add(new SignedBlockAndState(block, state));
final BeaconState updatedState =
state.updated(
w -> w.setLatestBlockHeader(BeaconBlockHeader.fromBlock(block.getMessage())));
blocks.add(new SignedBlockAndState(block, updatedState));
parentBlock = block;
}
return blocks;
Expand Down Expand Up @@ -2027,8 +2030,11 @@ public AnchorPoint createAnchorFromState(final BeaconState anchorState) {
final Bytes32 anchorRoot = anchorBlock.hashTreeRoot();
final UInt64 anchorEpoch = spec.getCurrentEpoch(anchorState);
final Checkpoint anchorCheckpoint = new Checkpoint(anchorEpoch, anchorRoot);
final BeaconState updatedAnchorState =
anchorState.updated(w -> w.setLatestBlockHeader(BeaconBlockHeader.fromBlock(anchorBlock)));

return AnchorPoint.create(spec, anchorCheckpoint, signedAnchorBlock, anchorState);
return AnchorPoint.create(
spec, anchorCheckpoint, updatedAnchorState, Optional.of(signedAnchorBlock));
}

public SignedContributionAndProof randomSignedContributionAndProof() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,15 @@ public void loadedInitialStateResource(
}
}

public void errorIncompatibleInitialState(final UInt64 epoch) {
log.error(
"Cannot start with provided initial state for the epoch {}, "
+ "checkpoint occurred on the empty slot, which is not yet supported.\n"
+ "If you are using remote checkpoint source, "
+ "please wait for the next epoch to finalize and retry.",
public void warningUnexpectedInitialState(
final UInt64 epoch, final UInt64 stateSlot, final UInt64 blockSlot) {
log.warn(
"Starting from state at slot {}, with block slot {}, which is not an anchor state. "
+ "Ensure that slots from {} - {} are empty. At epoch {}.",
stateSlot,
blockSlot,
stateSlot,
blockSlot,
epoch);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

package tech.pegasys.teku.services.beaconchain;

import static tech.pegasys.teku.infrastructure.exceptions.ExitConstants.ERROR_EXIT_CODE;
import static tech.pegasys.teku.infrastructure.logging.StatusLogger.STATUS_LOG;
import static tech.pegasys.teku.networks.Eth2NetworkConfiguration.FINALIZED_STATE_URL_PATH;

Expand Down Expand Up @@ -88,8 +87,10 @@ private AnchorPoint getAnchorPoint(
STATUS_LOG.loadingInitialStateResource(sanitizedResource);
final BeaconState state = ChainDataLoader.loadState(spec, stateResource);
if (state.getSlot().isGreaterThan(state.getLatestBlockHeader().getSlot())) {
STATUS_LOG.errorIncompatibleInitialState(spec.computeEpochAtSlot(state.getSlot()));
System.exit(ERROR_EXIT_CODE);
STATUS_LOG.warningUnexpectedInitialState(
spec.computeEpochAtSlot(state.getSlot()),
state.getSlot(),
state.getLatestBlockHeader().getSlot());
}
final AnchorPoint anchor = AnchorPoint.fromInitialState(spec, state);
STATUS_LOG.loadedInitialStateResource(
Expand Down
Loading

0 comments on commit 7386e4a

Please sign in to comment.