Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,8 @@ public SafeFuture<Optional<PayloadAttestationData>> createPayloadAttestationData
}
final SignedBeaconBlock block = maybeBlock.get();
final boolean payloadPresent =
executionPayloadManager.isExecutionPayloadRecentlySeen(block.getRoot());
executionPayloadManager.isExecutionPayloadAvailableForPayloadAttestation(
block.getRoot());
// if execution payload is in the store, blob data is available
final boolean blobDataAvailable =
combinedChainDataClient
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1446,7 +1446,8 @@ public void createPayloadAttestationData_shouldCreatePayloadAttestationData() {

when(chainDataClient.getBlockInEffectAtSlot(eq(newSlot)))
.thenReturn(SafeFuture.completedFuture(Optional.of(block)));
when(executionPayloadManager.isExecutionPayloadRecentlySeen(block.getRoot())).thenReturn(true);
when(executionPayloadManager.isExecutionPayloadAvailableForPayloadAttestation(block.getRoot()))
.thenReturn(true);

final Optional<PayloadAttestationData> result =
SafeFutureAssert.safeJoin(validatorApiHandler.createPayloadAttestationData(newSlot));
Expand All @@ -1461,6 +1462,29 @@ public void createPayloadAttestationData_shouldCreatePayloadAttestationData() {
});
}

@Test
public void createPayloadAttestationData_shouldSetPayloadPresentFalseWhenPayloadWasNotEarly() {
final UInt64 newSlot = UInt64.valueOf(25);
final SignedBeaconBlock block = dataStructureUtil.randomSignedBeaconBlock(newSlot);

when(chainDataClient.getBlockInEffectAtSlot(eq(newSlot)))
.thenReturn(SafeFuture.completedFuture(Optional.of(block)));
when(executionPayloadManager.isExecutionPayloadAvailableForPayloadAttestation(block.getRoot()))
.thenReturn(false);

final Optional<PayloadAttestationData> result =
SafeFutureAssert.safeJoin(validatorApiHandler.createPayloadAttestationData(newSlot));

assertThat(result)
.hasValueSatisfying(
payloadAttestationData -> {
assertThat(payloadAttestationData.getBeaconBlockRoot()).isEqualTo(block.getRoot());
assertThat(payloadAttestationData.getSlot()).isEqualTo(newSlot);
assertThat(payloadAttestationData.isPayloadPresent()).isFalse();
assertThat(payloadAttestationData.isBlobDataAvailable()).isFalse();
});
}

@Test
void sendPayloadAttestationMessages_shouldAddPayloadAttestationsToPool() {
final PayloadAttestationMessage payloadAttestationMessage =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"BALANCE_PER_ADDITIONAL_CUSTODY_GROUP" : "32000000000",
"EPOCHS_PER_SLASHINGS_VECTOR" : "8192",
"MIN_SLASHING_PENALTY_QUOTIENT" : "128",
"PAYLOAD_DUE_BPS" : "7500",
"MAX_BLS_TO_EXECUTION_CHANGES" : "16",
"CHURN_LIMIT_QUOTIENT_GLOAS" : "32768",
"DOMAIN_BEACON_ATTESTER" : "0x01000000",
Expand Down
18 changes: 18 additions & 0 deletions ethereum/spec/src/main/java/tech/pegasys/teku/spec/Spec.java
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,20 @@ public UInt64 computeTimeMillisAtSlot(final UInt64 slot, final UInt64 genesisTim
return atSlot(slot).miscHelpers().computeTimeMillisAtSlot(genesisTimeMillis, slot);
}

public boolean isTimeReached(final UInt64 currentTimeMillis, final UInt64 earliestTimeMillis) {
return currentTimeMillis.isGreaterThanOrEqualTo(earliestTimeMillis);
}

public boolean isBeforeTimeInSlot(
final UInt64 slot,
final UInt64 genesisTimeMillis,
final UInt64 currentTimeMillis,
final int timeInSlotMillisExclusive) {
return !isTimeReached(
currentTimeMillis,
computeTimeMillisAtSlot(slot, genesisTimeMillis).plus(timeInSlotMillisExclusive));
}

public Bytes computeSigningRoot(final BeaconBlock block, final Bytes32 domain) {
return atBlock(block).miscHelpers().computeSigningRoot(block, domain);
}
Expand Down Expand Up @@ -727,6 +741,10 @@ public Optional<Integer> getPayloadAttestationDueMillis(final UInt64 slot) {
return atSlot(slot).getForkChoiceUtil().getPayloadAttestationDueMillis();
}

public Optional<Integer> getPayloadDueMillis(final UInt64 slot) {
return atSlot(slot).getForkChoiceUtil().getPayloadDueMillis();
}

public Bytes32 getBlockRoot(final BeaconState state, final UInt64 epoch) {
return atState(state).beaconStateAccessors().getBlockRoot(state, epoch);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ public int getPayloadAttestationDueBps() {
return delegate.getPayloadAttestationDueBps();
}

@Override
public int getPayloadDueBps() {
return delegate.getPayloadDueBps();
}

@Override
public int getPtcSize() {
return delegate.getPtcSize();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ static SpecConfigGloas required(final SpecConfig specConfig) {

int getPayloadAttestationDueBps();

int getPayloadDueBps();

int getPtcSize();

int getMaxPayloadAttestations();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class SpecConfigGloasImpl extends DelegatingSpecConfigFulu implements Spe
private final int maxRequestPayloads;
private final int minBuilderWithdrawabilityDelay;
private final int payloadAttestationDueBps;
private final int payloadDueBps;
private final int ptcSize;
private final int syncMessageDueBps;
private final int churnLimitQuotientGloas;
Expand All @@ -47,6 +48,7 @@ public SpecConfigGloasImpl(
final int maxRequestPayloads,
final int minBuilderWithdrawabilityDelay,
final int payloadAttestationDueBps,
final int payloadDueBps,
final int ptcSize,
final int syncMessageDueBps,
final int churnLimitQuotientGloas,
Expand All @@ -64,6 +66,7 @@ public SpecConfigGloasImpl(
this.ptcSize = ptcSize;
this.minBuilderWithdrawabilityDelay = minBuilderWithdrawabilityDelay;
this.payloadAttestationDueBps = payloadAttestationDueBps;
this.payloadDueBps = payloadDueBps;
this.syncMessageDueBps = syncMessageDueBps;
this.churnLimitQuotientGloas = churnLimitQuotientGloas;
this.consolidationChurnLimitQuotient = consolidationChurnLimitQuotient;
Expand Down Expand Up @@ -100,6 +103,11 @@ public int getPayloadAttestationDueBps() {
return payloadAttestationDueBps;
}

@Override
public int getPayloadDueBps() {
return payloadDueBps;
}

@Override
public int getPtcSize() {
return ptcSize;
Expand Down Expand Up @@ -171,6 +179,7 @@ public boolean equals(final Object o) {
&& maxRequestPayloads == that.maxRequestPayloads
&& minBuilderWithdrawabilityDelay == that.minBuilderWithdrawabilityDelay
&& payloadAttestationDueBps == that.payloadAttestationDueBps
&& payloadDueBps == that.payloadDueBps
&& ptcSize == that.ptcSize
&& syncMessageDueBps == that.syncMessageDueBps
&& builderRegistryLimit == that.builderRegistryLimit
Expand All @@ -196,6 +205,7 @@ public int hashCode() {
maxRequestPayloads,
minBuilderWithdrawabilityDelay,
payloadAttestationDueBps,
payloadDueBps,
ptcSize,
syncMessageDueBps,
churnLimitQuotientGloas,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class GloasBuilder extends BaseForkBuilder
private Integer maxRequestPayloads;
private Integer minBuilderWithdrawabilityDelay;
private Integer payloadAttestationDueBps;
private Integer payloadDueBps;
private Integer syncMessageDueBpsGloas;

// gloas preset
Expand Down Expand Up @@ -64,6 +65,7 @@ public SpecConfigAndParent<SpecConfigGloas> build(
maxRequestPayloads,
minBuilderWithdrawabilityDelay,
payloadAttestationDueBps,
payloadDueBps,
ptcSize,
syncMessageDueBpsGloas,
churnLimitQuotientGloas,
Expand Down Expand Up @@ -108,6 +110,12 @@ public GloasBuilder payloadAttestationDueBps(final Integer payloadAttestationDue
return this;
}

public GloasBuilder payloadDueBps(final Integer payloadDueBps) {
checkNotNull(payloadDueBps);
this.payloadDueBps = payloadDueBps;
return this;
}

public GloasBuilder syncMessageDueBpsGloas(final Integer syncMessageDueBpsGloas) {
checkNotNull(syncMessageDueBpsGloas);
this.syncMessageDueBpsGloas = syncMessageDueBpsGloas;
Expand Down Expand Up @@ -179,6 +187,7 @@ public Map<String, Object> getValidationMap() {
constants.put("maxRequestPayloads", maxRequestPayloads);
constants.put("minBuilderWithdrawabilityDelay", minBuilderWithdrawabilityDelay);
constants.put("payloadAttestationDueBps", payloadAttestationDueBps);
constants.put("payloadDueBps", payloadDueBps);
constants.put("syncMessageDueBpsGloas", syncMessageDueBpsGloas);

constants.put("builderRegistryLimit", builderRegistryLimit);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,11 @@ public Optional<Integer> getPayloadAttestationDueMillis() {
return Optional.empty();
}

// get_payload_due_ms
public Optional<Integer> getPayloadDueMillis() {
return Optional.empty();
}

private boolean isExecutionBlock(final ReadOnlyStore store, final SignedBeaconBlock block) {
// post-Bellatrix: always true
final BeaconBlockBody body = block.getMessage().getBody();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ public Optional<Integer> getPayloadAttestationDueMillis() {
return Optional.of(getSlotComponentDurationMillis(configGloas.getPayloadAttestationDueBps()));
}

@Override
public Optional<Integer> getPayloadDueMillis() {
final SpecConfigGloas configGloas = SpecConfigGloas.required(specConfig);
return Optional.of(getSlotComponentDurationMillis(configGloas.getPayloadDueBps()));
}

/**
* Computes dual block timeliness for Gloas: attestation deadline and PTC deadline.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ SYNC_MESSAGE_DUE_BPS_GLOAS: 2500
# 5000 basis points, 50% of SLOT_DURATION_MS
CONTRIBUTION_DUE_BPS_GLOAS: 5000
# 7500 basis points, 75% of SLOT_DURATION_MS
PAYLOAD_DUE_BPS: 7500
# 7500 basis points, 75% of SLOT_DURATION_MS
PAYLOAD_ATTESTATION_DUE_BPS: 7500
# EIP-8061
# 2**15 (= 32,768)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ SYNC_MESSAGE_DUE_BPS_GLOAS: 2500
# 5000 basis points, 50% of SLOT_DURATION_MS
CONTRIBUTION_DUE_BPS_GLOAS: 5000
# 7500 basis points, 75% of SLOT_DURATION_MS
PAYLOAD_DUE_BPS: 7500
# 7500 basis points, 75% of SLOT_DURATION_MS
PAYLOAD_ATTESTATION_DUE_BPS: 7500
# EIP-8061
# [customized] 2**4 (= 16)
Expand Down Expand Up @@ -217,4 +219,4 @@ MAX_BYTES_PER_INCLUSION_LIST: 8192
# Blob Scheduling
# ---------------------------------------------------------------

BLOB_SCHEDULE: []
BLOB_SCHEDULE: []
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ SYNC_MESSAGE_DUE_BPS_GLOAS: 2500
# 5000 basis points, 50% of SLOT_DURATION_MS
CONTRIBUTION_DUE_BPS_GLOAS: 5000
# 7500 basis points, 75% of SLOT_DURATION_MS
PAYLOAD_DUE_BPS: 7500
# 7500 basis points, 75% of SLOT_DURATION_MS
PAYLOAD_ATTESTATION_DUE_BPS: 7500
# EIP-8061
# [customized] 2**4 (= 16)
Expand Down Expand Up @@ -199,4 +201,4 @@ BALANCE_PER_ADDITIONAL_CUSTODY_GROUP: 32000000000

# Gloas
# 2**7 (= 128) payloads
MAX_REQUEST_PAYLOADS: 128
MAX_REQUEST_PAYLOADS: 128
37 changes: 37 additions & 0 deletions ethereum/spec/src/test/java/tech/pegasys/teku/spec/SpecTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,41 @@ void shouldComputeFirstSlotWithDataColumnSidecarSupportWhenFuluIsSupported() {
assertThat(fuluSpec.computeFirstSlotWithDataColumnSidecarSupport())
.contains(fuluSpec.computeStartSlotAtEpoch(fuluForkEpoch));
}

@Test
void isTimeReached_shouldReturnFalseWhenTimeNotReached() {
final UInt64 currentTimeMillis = UInt64.valueOf(1_000);

assertThat(spec.isTimeReached(currentTimeMillis, currentTimeMillis.plus(1))).isFalse();
}

@Test
void isTimeReached_shouldReturnTrueWhenTimeMatches() {
final UInt64 currentTimeMillis = UInt64.valueOf(1_000);

assertThat(spec.isTimeReached(currentTimeMillis, currentTimeMillis)).isTrue();
}

@Test
void isBeforeTimeInSlot_shouldExcludeAllowedTimeInSlot() {
final UInt64 genesisTimeMillis = UInt64.valueOf(1_000);
final UInt64 slot = UInt64.valueOf(3);
final UInt64 slotStartTimeMillis = spec.computeTimeMillisAtSlot(slot, genesisTimeMillis);
final int timeInSlotMillisExclusive = 2_000;

assertThat(
spec.isBeforeTimeInSlot(
slot,
genesisTimeMillis,
slotStartTimeMillis.plus(timeInSlotMillisExclusive).minus(1),
timeInSlotMillisExclusive))
.isTrue();
assertThat(
spec.isBeforeTimeInSlot(
slot,
genesisTimeMillis,
slotStartTimeMillis.plus(timeInSlotMillisExclusive),
timeInSlotMillisExclusive))
.isFalse();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ public void equals_mainnet() {
assertThat(configA.hashCode()).isEqualTo(configB.hashCode());
}

@Test
public void shouldLoadPayloadDueBps() {
final SpecConfigGloas config =
SpecConfigLoader.loadConfig("minimal").specConfig().toVersionGloas().orElseThrow();

assertThat(config.getPayloadDueBps()).isEqualTo(7500);
}

@Test
public void equals_sameRandomValues() {
final SpecConfigFulu specConfigFulu =
Expand Down Expand Up @@ -94,6 +102,7 @@ private SpecConfigGloas createRandomGloasConfig(final SpecConfigFulu fuluConfig,
dataStructureUtil.randomPositiveInt(12000),
dataStructureUtil.randomPositiveInt(512),
dataStructureUtil.randomPositiveInt(12000),
dataStructureUtil.randomPositiveInt(12000),
dataStructureUtil.randomPositiveInt(65536),
dataStructureUtil.randomPositiveInt(65536),
dataStructureUtil.randomUInt64()) {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ void computeBlockTimeliness_shouldMarkBlockLateForAttestationsAndPtcAtPtcDeadlin
.isEqualTo(new BlockTimeliness(false, false));
}

@Test
void getPayloadDueMillis_shouldUsePayloadDueBps() {
assertThat(forkChoiceUtil.getPayloadDueMillis())
.hasValue(spec.getSlotDurationMillis(gloasSlot) * 3 / 4);
assertThat(forkChoiceUtil.getPayloadDueMillis())
.isEqualTo(forkChoiceUtil.getPayloadAttestationDueMillis());
}

@Test
void
computeBlockTimeliness_shouldMarkBlockLateForAttestationsAndPtcWhenBlockIsNotFromCurrentSlot() {
Expand Down
Loading
Loading