Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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 @@ -16,6 +16,7 @@
import com.google.common.io.Resources;
import java.net.URL;
import java.util.Map;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import tech.pegasys.teku.ethereum.execution.types.Eth1Address;
import tech.pegasys.teku.infrastructure.time.SystemTimeProvider;
Expand All @@ -30,6 +31,7 @@
import tech.pegasys.teku.test.acceptance.dsl.TekuNodeConfigBuilder;
import tech.pegasys.teku.test.acceptance.dsl.tools.deposits.ValidatorKeystores;

@Disabled("Requires Besu to support FcU with updated PayloadAttributes")
public class GloasUpgradeAcceptanceTest extends AcceptanceTestBase {

private static final String NETWORK_NAME = "swift";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,21 @@ public class PayloadAttributesV4 extends PayloadAttributesV3 {
@JsonDeserialize(using = UInt64AsHexDeserializer.class)
public final UInt64 slotNumber;

@JsonSerialize(using = UInt64AsHexSerializer.class)
@JsonDeserialize(using = UInt64AsHexDeserializer.class)
public final UInt64 targetGasLimit;

public PayloadAttributesV4(
final @JsonProperty("timestamp") UInt64 timestamp,
final @JsonProperty("prevRandao") Bytes32 prevRandao,
final @JsonProperty("suggestedFeeRecipient") Bytes20 suggestedFeeRecipient,
final @JsonProperty("withdrawals") List<WithdrawalV1> withdrawals,
final @JsonProperty("parentBeaconBlockRoot") Bytes32 parentBeaconBlockRoot,
final @JsonProperty("slotNumber") UInt64 slotNumber) {
final @JsonProperty("slotNumber") UInt64 slotNumber,
final @JsonProperty("targetGasLimit") UInt64 targetGasLimit) {
super(timestamp, prevRandao, suggestedFeeRecipient, withdrawals, parentBeaconBlockRoot);
this.slotNumber = slotNumber;
this.targetGasLimit = targetGasLimit;
}

public static PayloadAttributesV4 fromInternalPayloadBuildingAttributesV4(
Expand All @@ -51,7 +57,8 @@ public static PayloadAttributesV4 fromInternalPayloadBuildingAttributesV4(
payloadBuildingAttributes.feeRecipient(),
getWithdrawals(payloadBuildingAttributes),
payloadBuildingAttributes.parentBeaconBlock().blockRoot(),
payloadBuildingAttributes.proposalSlot());
payloadBuildingAttributes.proposalSlot(),
payloadBuildingAttributes.targetGasLimit());
}

@Override
Expand All @@ -66,12 +73,13 @@ public boolean equals(final Object o) {
return false;
}
final PayloadAttributesV4 that = (PayloadAttributesV4) o;
return Objects.equals(slotNumber, that.slotNumber);
return Objects.equals(slotNumber, that.slotNumber)
&& Objects.equals(targetGasLimit, that.targetGasLimit);
}

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), slotNumber);
return Objects.hash(super.hashCode(), slotNumber, targetGasLimit);
}

@Override
Expand All @@ -83,6 +91,7 @@ public String toString() {
.add("withdrawals", withdrawals)
.add("parentBeaconBlockRoot", parentBeaconBlockRoot)
.add("slotNumber", slotNumber)
.add("targetGasLimit", targetGasLimit)
.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.List;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.units.bigints.UInt256;
Expand All @@ -37,6 +38,7 @@
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceStateV1;
import tech.pegasys.teku.ethereum.executionclient.schema.ForkChoiceUpdatedResult;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadAttributesV1;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadAttributesV4;
import tech.pegasys.teku.ethereum.executionclient.schema.PayloadStatusV1;
import tech.pegasys.teku.ethereum.executionclient.serialization.Bytes20Deserializer;
import tech.pegasys.teku.ethereum.executionclient.serialization.Bytes20Serializer;
Expand Down Expand Up @@ -257,6 +259,26 @@ void shouldSerializeDeserializePayloadAttributesV1() throws IOException {
assertThat(payloadAttributesV1Orig).isEqualTo(payloadAttributesV1New);
}

@TestTemplate
void shouldSerializeDeserializePayloadAttributesV4() throws IOException {
PayloadAttributesV4 payloadAttributesV4Orig =
new PayloadAttributesV4(
dataStructureUtil.randomUInt64(),
dataStructureUtil.randomBytes32(),
dataStructureUtil.randomBytes20(),
List.of(),
dataStructureUtil.randomBytes32(),
dataStructureUtil.randomUInt64(),
dataStructureUtil.randomUInt64());

String payloadAttributesV4OrigSerialized =
objectMapper.writeValueAsString(payloadAttributesV4Orig);
PayloadAttributesV4 payloadAttributesV4New =
objectMapper.readValue(payloadAttributesV4OrigSerialized, PayloadAttributesV4.class);

assertThat(payloadAttributesV4Orig).isEqualTo(payloadAttributesV4New);
}

@TestTemplate
void shouldSerializeDeserializeExecutionPayloadV1() throws IOException {
ExecutionPayload internalExecutionPayload = dataStructureUtil.randomExecutionPayload();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ public void shouldCallForkChoiceUpdateV4WithPayloadAttributesV4WhenInGloas() {
ForkChoiceStateV1.fromInternalForkChoiceState(forkChoiceState);
final PayloadAttributesV4 payloadAttributesV4 =
PayloadAttributesV4.fromInternalPayloadBuildingAttributesV4(payloadBuildingAttributes);
assertThat(payloadAttributesV4.targetGasLimit)
.isEqualTo(payloadBuildingAttributes.targetGasLimit());

jsonRpcMethod = new EngineForkChoiceUpdatedV4(executionEngineClient);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,18 +136,21 @@ void engineForkChoiceUpdated_shouldCallEngineForkChoiceUpdatedV4() {
final ForkChoiceState forkChoiceState = dataStructureUtil.randomForkChoiceState(false);
final ForkChoiceStateV1 forkChoiceStateV1 =
ForkChoiceStateV1.fromInternalForkChoiceState(forkChoiceState);
final UInt64 targetGasLimit = dataStructureUtil.randomUInt64();
final PayloadBuildingAttributes attributes =
new PayloadBuildingAttributes(
dataStructureUtil.randomUInt64(),
dataStructureUtil.randomUInt64(),
dataStructureUtil.randomUInt64(),
dataStructureUtil.randomBytes32(),
dataStructureUtil.randomEth1Address(),
targetGasLimit,
Optional.empty(),
Optional.of(List.of()),
ForkChoiceNode.createBase(dataStructureUtil.randomBytes32()));
final PayloadAttributesV4 payloadAttributes =
PayloadAttributesV4.fromInternalPayloadBuildingAttributesV4(attributes);
assertThat(payloadAttributes.targetGasLimit).isEqualTo(targetGasLimit);
final ForkChoiceUpdatedResult responseData =
new ForkChoiceUpdatedResult(
new PayloadStatusV1(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,32 @@ public record PayloadBuildingAttributes(
UInt64 timestamp,
Bytes32 prevRandao,
Eth1Address feeRecipient,
UInt64 targetGasLimit,
Optional<SignedValidatorRegistration> validatorRegistration,
Optional<List<Withdrawal>> withdrawals,
ForkChoiceNode parentBeaconBlock) {

public PayloadBuildingAttributes(
final UInt64 proposerIndex,
final UInt64 proposalSlot,
final UInt64 timestamp,
final Bytes32 prevRandao,
final Eth1Address feeRecipient,
final Optional<SignedValidatorRegistration> validatorRegistration,
final Optional<List<Withdrawal>> withdrawals,
final ForkChoiceNode parentBeaconBlock) {
this(
proposerIndex,
proposalSlot,
timestamp,
prevRandao,
feeRecipient,
UInt64.ZERO,
validatorRegistration,
withdrawals,
parentBeaconBlock);
}

public Optional<BLSPublicKey> getValidatorRegistrationPublicKey() {
return validatorRegistration.map(
signedValidatorRegistration -> signedValidatorRegistration.getMessage().getPublicKey());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1996,6 +1996,7 @@ public PayloadBuildingAttributes randomPayloadBuildingAttributes(
randomUInt64(),
randomBytes32(),
randomEth1Address(),
randomUInt64(),
withValidatorRegistration
? Optional.of(randomSignedValidatorRegistration())
: Optional.empty(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import static tech.pegasys.teku.infrastructure.logging.ValidatorLogger.VALIDATOR_LOGGER;

import com.google.common.annotations.VisibleForTesting;
import java.util.Collection;
import java.util.List;
import java.util.Map;
Expand All @@ -35,6 +36,7 @@
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.spec.datastructures.blocks.SlotAndBlockRoot;
import tech.pegasys.teku.spec.datastructures.builder.SignedValidatorRegistration;
import tech.pegasys.teku.spec.datastructures.epbs.versions.gloas.ProposerPreferences;
import tech.pegasys.teku.spec.datastructures.epbs.versions.gloas.SignedBlindedExecutionPayloadEnvelope;
import tech.pegasys.teku.spec.datastructures.execution.versions.capella.Withdrawal;
import tech.pegasys.teku.spec.datastructures.execution.versions.electra.ExecutionRequests;
Expand All @@ -45,6 +47,7 @@
import tech.pegasys.teku.spec.executionlayer.ExecutionLayerChannel;
import tech.pegasys.teku.spec.executionlayer.ForkChoiceState;
import tech.pegasys.teku.spec.executionlayer.PayloadBuildingAttributes;
import tech.pegasys.teku.statetransition.execution.ProposerPreferencesManager;
import tech.pegasys.teku.storage.client.ChainHead;
import tech.pegasys.teku.storage.client.RecentChainData;
import tech.pegasys.teku.storage.client.ValidatorIsConnectedProvider;
Expand All @@ -64,6 +67,7 @@ public class ProposersDataManager implements SlotEventsChannel, ValidatorIsConne
new ConcurrentHashMap<>();
private final Optional<Eth1Address> proposerDefaultFeeRecipient;
private final boolean forkChoiceUpdatedAlwaysSendPayloadAttribute;
private final ProposerPreferencesManager proposerPreferencesManager;

public ProposersDataManager(
final EventThread eventThread,
Expand All @@ -73,6 +77,26 @@ public ProposersDataManager(
final RecentChainData recentChainData,
final Optional<Eth1Address> proposerDefaultFeeRecipient,
final boolean forkChoiceUpdatedAlwaysSendPayloadAttribute) {
this(
eventThread,
spec,
metricsSystem,
executionLayerChannel,
recentChainData,
proposerDefaultFeeRecipient,
forkChoiceUpdatedAlwaysSendPayloadAttribute,
ProposerPreferencesManager.NOOP);
}

public ProposersDataManager(
final EventThread eventThread,
final Spec spec,
final MetricsSystem metricsSystem,
final ExecutionLayerChannel executionLayerChannel,
final RecentChainData recentChainData,
final Optional<Eth1Address> proposerDefaultFeeRecipient,
final boolean forkChoiceUpdatedAlwaysSendPayloadAttribute,
final ProposerPreferencesManager proposerPreferencesManager) {
final LabelledSuppliedMetric labelledGauge =
metricsSystem.createLabelledSuppliedGauge(
TekuMetricCategory.BEACON,
Expand All @@ -89,6 +113,7 @@ public ProposersDataManager(
this.recentChainData = recentChainData;
this.proposerDefaultFeeRecipient = proposerDefaultFeeRecipient;
this.forkChoiceUpdatedAlwaysSendPayloadAttribute = forkChoiceUpdatedAlwaysSendPayloadAttribute;
this.proposerPreferencesManager = proposerPreferencesManager;
}

@Override
Expand Down Expand Up @@ -259,6 +284,8 @@ private SafeFuture<Optional<PayloadBuildingAttributes>> calculatePayloadBuilding
.map(RegisteredValidatorInfo::getSignedValidatorRegistration);

final Eth1Address feeRecipient = getFeeRecipient(proposerInfo, blockSlot);
final UInt64 targetGasLimit =
getTargetGasLimit(blockSlot, proposerIndex, validatorRegistration);

return getPayloadAttributeWithdrawals(currentHeadBlock, state)
.thenApplyAsync(
Expand All @@ -270,6 +297,7 @@ private SafeFuture<Optional<PayloadBuildingAttributes>> calculatePayloadBuilding
timestamp,
random,
feeRecipient,
targetGasLimit,
validatorRegistration,
withdrawals,
currentHeadBlock)),
Expand Down Expand Up @@ -317,6 +345,22 @@ private SafeFuture<Optional<BeaconState>> getStateForPayloadBuildingAttributes(
new SlotAndBlockRoot(blockSlot, forkChoiceState.headBlock().blockRoot()));
}

@VisibleForTesting
UInt64 getTargetGasLimit(
final UInt64 blockSlot,
final UInt64 proposerIndex,
final Optional<SignedValidatorRegistration> validatorRegistration) {
return proposerPreferencesManager
.getProposerPreferences(blockSlot)
.filter(
proposerPreferences -> proposerPreferences.getValidatorIndex().equals(proposerIndex))
.map(ProposerPreferences::getGasLimit)
.or(
() ->
validatorRegistration.map(registration -> registration.getMessage().getGasLimit()))
.orElse(UInt64.ZERO);
}

// this function MUST return a fee recipient.
private Eth1Address getFeeRecipient(
final PreparedProposerInfo preparedProposerInfo, final UInt64 blockSlot) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,9 @@ private PayloadBuildingAttributes getExpectedPayloadBuildingAttributes(
timestamp,
random,
feeRecipient,
validatorRegistration
.map(registration -> registration.getMessage().getGasLimit())
.orElse(UInt64.ZERO),
validatorRegistration,
dataStructureUtil.randomWithdrawalList(),
forkChoiceState.headBlock());
Expand Down
Loading
Loading