Skip to content

Commit

Permalink
improve blinded block validator options
Browse files Browse the repository at this point in the history
  • Loading branch information
tbenr committed Apr 14, 2022
1 parent 4116197 commit 6c816e2
Show file tree
Hide file tree
Showing 16 changed files with 125 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,20 @@ public void shouldSignBlock() {
assertThat(result).isCompletedWithValue(expectedSignature);
}

@Test
public void shouldSignBlindedBlock() {
final BeaconBlock block = dataStructureUtil.randomBlindedBeaconBlock(10);
final BLSSignature expectedSignature =
BLSSignature.fromBytesCompressed(
Bytes.fromBase64String(
"pbSSuf7h70JkzI/U157flTWPZDuaBXgRLj1HLMoCwjA4Xd0hMdGewn7G2HLZiQcNC9G6FSd1+0BT5PwknYez4ya6TccwpaGnsvWYLPf3SNIX5Ug7Yi1CF1fvEr3x9sZ0"));

final SafeFuture<BLSSignature> result = signer.signBlock(block, fork);
asyncRunner.executeQueuedActions();

assertThat(result).isCompletedWithValue(expectedSignature);
}

@Test
public void shouldCreateRandaoReveal() {
final BLSSignature expectedSignature =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,10 @@ public BeaconBlock randomBeaconBlock(UInt64 slotNum) {
body);
}

public BeaconBlock randomBlindedBeaconBlock(long slotNum) {
return randomBlindedBeaconBlock(UInt64.valueOf(slotNum));
}

public BeaconBlock randomBlindedBeaconBlock(UInt64 slotNum) {
final UInt64 proposerIndex = randomUInt64();
Bytes32 previousRoot = randomBytes32();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

package tech.pegasys.teku.cli.options;

import static tech.pegasys.teku.validator.api.ValidatorConfig.DEFAULT_VALIDATOR_BLINDED_BLOCKS_ENABLED;

import java.nio.file.Path;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes32;
Expand Down Expand Up @@ -102,16 +100,6 @@ public class ValidatorOptions {
arity = "0..1")
private boolean generateEarlyAttestations = ValidatorConfig.DEFAULT_GENERATE_EARLY_ATTESTATIONS;

@Option(
names = {"--Xvalidators-blinded-blocks-api-enabled"},
paramLabel = "<BOOLEAN>",
showDefaultValue = Visibility.ALWAYS,
description = "Use blinded block api calls",
fallbackValue = "true",
hidden = true,
arity = "0..1")
private boolean blindedBlocksApiEnabled = DEFAULT_VALIDATOR_BLINDED_BLOCKS_ENABLED;

public void configure(TekuConfiguration.Builder builder) {
if (validatorPerformanceTrackingEnabled != null) {
if (validatorPerformanceTrackingEnabled) {
Expand All @@ -125,7 +113,6 @@ public void configure(TekuConfiguration.Builder builder) {
config ->
config
.validatorKeystoreLockingEnabled(validatorKeystoreLockingEnabled)
.blindedBeaconBlocksApiEnabled(blindedBlocksApiEnabled)
.validatorPerformanceTrackingMode(validatorPerformanceTrackingMode)
.validatorExternalSignerSlashingProtectionEnabled(
validatorExternalSignerSlashingProtectionEnabled)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

package tech.pegasys.teku.cli.options;

import static tech.pegasys.teku.validator.api.ValidatorConfig.DEFAULT_VALIDATOR_BLINDED_BLOCKS_ENABLED;

import picocli.CommandLine.Help.Visibility;
import picocli.CommandLine.Option;
import tech.pegasys.teku.config.TekuConfiguration;
Expand Down Expand Up @@ -56,13 +58,24 @@ public class ValidatorProposerOptions {
private boolean proposerMevBoostEnabled =
ValidatorConfig.DEFAULT_VALIDATOR_PROPOSER_MEV_BOOST_ENABLED;

@Option(
names = {"--Xvalidators-proposer-blinded-blocks-enabled"},
paramLabel = "<BOOLEAN>",
showDefaultValue = Visibility.ALWAYS,
description = "Use blinded blocks when in block production duties",
fallbackValue = "true",
hidden = true,
arity = "0..1")
private boolean blindedBlocksEnabled = DEFAULT_VALIDATOR_BLINDED_BLOCKS_ENABLED;

public void configure(TekuConfiguration.Builder builder) {
builder.validator(
config ->
config
.proposerDefaultFeeRecipient(proposerDefaultFeeRecipient)
.proposerConfigSource(proposerConfig)
.refreshProposerConfigFromSource(proposerConfigRefreshEnabled)
.proposerMevBoostEnabled(proposerMevBoostEnabled));
.proposerMevBoostEnabled(proposerMevBoostEnabled)
.blindedBeaconBlocksEnabled(blindedBlocksEnabled));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

package tech.pegasys.teku.cli.subcommand;

import static tech.pegasys.teku.validator.api.ValidatorConfig.DEFAULT_VALIDATOR_BLINDED_BLOCKS_ENABLED;

import java.net.URI;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -91,7 +89,6 @@ static OkHttpValidatorRestApiClient createApiClient(final URI baseEndpoint) {
// Strip any authentication info from the URL to ensure it doesn't get logged.
apiEndpoint = apiEndpoint.newBuilder().username("").password("").build();
final OkHttpClient okHttpClient = httpClientBuilder.build();
return new OkHttpValidatorRestApiClient(
apiEndpoint, okHttpClient, DEFAULT_VALIDATOR_BLINDED_BLOCKS_ENABLED);
return new OkHttpValidatorRestApiClient(apiEndpoint, okHttpClient);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,36 @@ public void shouldReportAddressIfFeeRecipientSpecified() {

@Test
public void shouldEnableBlindedBeaconBlocks() {
final String[] args = {"--Xvalidators-blinded-blocks-api-enabled", "true"};
final String[] args = {"--Xvalidators-proposer-blinded-blocks-enabled", "true"};
final TekuConfiguration config = getTekuConfigurationFromArguments(args);
assertThat(config.validatorClient().getValidatorConfig().isBlindedBeaconBlocksApiEnabled())
assertThat(config.validatorClient().getValidatorConfig().isBlindedBeaconBlocksEnabled())
.isTrue();
}

@Test
public void shouldNotUseBlindedBeaconBlocksByDefault() {
final String[] args = {};
final TekuConfiguration config = getTekuConfigurationFromArguments(args);
assertThat(config.validatorClient().getValidatorConfig().isBlindedBeaconBlocksApiEnabled())
assertThat(config.validatorClient().getValidatorConfig().isBlindedBeaconBlocksEnabled())
.isFalse();
}

@Test
public void shouldEnableMevBoost() {
final String[] args = {
"--Xvalidators-proposer-mev-boost-enabled",
"true",
"--Xvalidators-proposer-blinded-blocks-enabled",
"true"
};
final TekuConfiguration config = getTekuConfigurationFromArguments(args);
assertThat(config.validatorClient().getValidatorConfig().isProposerMevBoostEnabled()).isTrue();
}

@Test
public void shouldNotUseMevBoostByDefault() {
final String[] args = {};
final TekuConfiguration config = getTekuConfigurationFromArguments(args);
assertThat(config.validatorClient().getValidatorConfig().isProposerMevBoostEnabled()).isFalse();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public class ValidatorConfig {
private final Optional<Eth1Address> proposerDefaultFeeRecipient;
private final Optional<String> proposerConfigSource;
private final boolean refreshProposerConfigFromSource;
private final boolean blindedBeaconBlocksApiEnabled;
private final boolean blindedBeaconBlocksEnabled;
private final boolean proposerMevBoostEnabled;

private ValidatorConfig(
Expand All @@ -83,7 +83,7 @@ private ValidatorConfig(
final Optional<String> proposerConfigSource,
final boolean refreshProposerConfigFromSource,
final boolean proposerMevBoostEnabled,
final boolean blindedBeaconBlocksApiEnabled) {
final boolean blindedBeaconBlocksEnabled) {
this.validatorKeys = validatorKeys;
this.validatorExternalSignerPublicKeySources = validatorExternalSignerPublicKeySources;
this.validatorExternalSignerUrl = validatorExternalSignerUrl;
Expand All @@ -105,7 +105,7 @@ private ValidatorConfig(
this.proposerDefaultFeeRecipient = proposerDefaultFeeRecipient;
this.proposerConfigSource = proposerConfigSource;
this.refreshProposerConfigFromSource = refreshProposerConfigFromSource;
this.blindedBeaconBlocksApiEnabled = blindedBeaconBlocksApiEnabled;
this.blindedBeaconBlocksEnabled = blindedBeaconBlocksEnabled;
this.proposerMevBoostEnabled = proposerMevBoostEnabled;
}

Expand Down Expand Up @@ -180,8 +180,8 @@ public boolean getRefreshProposerConfigFromSource() {
return refreshProposerConfigFromSource;
}

public boolean isBlindedBeaconBlocksApiEnabled() {
return blindedBeaconBlocksApiEnabled;
public boolean isBlindedBeaconBlocksEnabled() {
return blindedBeaconBlocksEnabled;
}

public boolean isProposerMevBoostEnabled() {
Expand Down Expand Up @@ -222,7 +222,7 @@ public static final class Builder {
private boolean refreshProposerConfigFromSource =
DEFAULT_VALIDATOR_PROPOSER_CONFIG_REFRESH_ENABLED;
private boolean proposerMevBoostEnabled = DEFAULT_VALIDATOR_PROPOSER_MEV_BOOST_ENABLED;
private boolean blindedBlocksApiEnabled = DEFAULT_VALIDATOR_BLINDED_BLOCKS_ENABLED;
private boolean blindedBlocksEnabled = DEFAULT_VALIDATOR_BLINDED_BLOCKS_ENABLED;

private Builder() {}

Expand Down Expand Up @@ -353,8 +353,8 @@ public Builder proposerMevBoostEnabled(final boolean proposerMevBoostEnabled) {
return this;
}

public Builder blindedBeaconBlocksApiEnabled(final boolean blindedBeaconBlockEnabled) {
this.blindedBlocksApiEnabled = blindedBeaconBlockEnabled;
public Builder blindedBeaconBlocksEnabled(final boolean blindedBeaconBlockEnabled) {
this.blindedBlocksEnabled = blindedBeaconBlockEnabled;
return this;
}

Expand All @@ -363,6 +363,7 @@ public ValidatorConfig build() {
validateExternalSignerKeystoreAndPasswordFileConfig();
validateExternalSignerTruststoreAndPasswordFileConfig();
validateExternalSignerURLScheme();
validateMevBoostAndBlindedBlocks();
return new ValidatorConfig(
validatorKeys,
validatorExternalSignerPublicKeySources,
Expand All @@ -383,7 +384,7 @@ public ValidatorConfig build() {
proposerConfigSource,
refreshProposerConfigFromSource,
proposerMevBoostEnabled,
blindedBlocksApiEnabled);
blindedBlocksEnabled);
}

private void validateExternalSignerUrlAndPublicKeys() {
Expand Down Expand Up @@ -432,6 +433,14 @@ private void validateExternalSignerURLScheme() {
}
}

private void validateMevBoostAndBlindedBlocks() {
if (proposerMevBoostEnabled && !blindedBlocksEnabled) {
final String errorMessage =
"Invalid configuration. '--Xvalidators-proposer-mev-boost-enabled' requires '--Xvalidators-proposer-blinded-blocks-enabled' to be enabled as well.";
throw new InvalidConfigurationException(errorMessage);
}
}

private static boolean isURLSchemeHttps(final URL url) {
final String protocol = url.getProtocol();
return protocol != null && protocol.equalsIgnoreCase("https");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

package tech.pegasys.teku.validator.api;

import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.net.MalformedURLException;
import java.net.URI;
import java.nio.file.Path;
Expand Down Expand Up @@ -165,6 +167,12 @@ public void bellatrix_shouldNotThrowIfValidationIsActiveAndProposerConfigSourceI
verifyProposerConfigOrProposerDefaultFeeRecipientNotThrow(config);
}

@Test
public void shouldThrowIfMevBoostIsWithoutBlindedBeaconBlocks() {
assertThatThrownBy(() -> configBuilder.proposerMevBoostEnabled(true).build())
.isInstanceOf(InvalidConfigurationException.class);
}

void verifyProposerConfigOrProposerDefaultFeeRecipientNotThrow(final ValidatorConfig config) {
Assertions.assertThatCode(config::getProposerDefaultFeeRecipient).doesNotThrowAnyException();
Assertions.assertThatCode(config::getProposerConfigSource).doesNotThrowAnyException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ public static ValidatorClientService create(
final AsyncRunner asyncRunner = services.createAsyncRunner("validator");
final boolean generateEarlyAttestations =
config.getValidatorConfig().generateEarlyAttestations();
final boolean blindedBlocksEnabled =
config.getValidatorConfig().isBlindedBeaconBlocksApiEnabled();
final BeaconNodeApi beaconNodeApi =
config
.getValidatorConfig()
Expand All @@ -112,8 +110,7 @@ public static ValidatorClientService create(
asyncRunner,
endpoint,
config.getSpec(),
generateEarlyAttestations,
blindedBlocksEnabled))
generateEarlyAttestations))
.orElseGet(
() ->
InProcessBeaconNodeApi.create(
Expand Down Expand Up @@ -194,7 +191,11 @@ private void initializeValidators(
this.validatorIndexProvider =
new ValidatorIndexProvider(validators, validatorApiChannel, asyncRunner);
final BlockDutyFactory blockDutyFactory =
new BlockDutyFactory(forkProvider, validatorApiChannel, spec);
new BlockDutyFactory(
forkProvider,
validatorApiChannel,
config.getValidatorConfig().isBlindedBeaconBlocksEnabled(),
spec);
final AttestationDutyFactory attestationDutyFactory =
new AttestationDutyFactory(spec, forkProvider, validatorApiChannel);
final BeaconCommitteeSubscriptions beaconCommitteeSubscriptions =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,23 @@ public class BlockDutyFactory implements DutyFactory<BlockProductionDuty, Duty>
private final ForkProvider forkProvider;
private final ValidatorApiChannel validatorApiChannel;
private final Spec spec;
private final boolean useBlindedBlock;

public BlockDutyFactory(
final ForkProvider forkProvider,
final ValidatorApiChannel validatorApiChannel,
final boolean useBlindedBlock,
final Spec spec) {
this.forkProvider = forkProvider;

this.useBlindedBlock = useBlindedBlock;
this.validatorApiChannel = validatorApiChannel;
this.spec = spec;
}

@Override
public BlockProductionDuty createProductionDuty(final UInt64 slot, final Validator validator) {
return new BlockProductionDuty(validator, slot, forkProvider, validatorApiChannel, spec);
return new BlockProductionDuty(
validator, slot, forkProvider, validatorApiChannel, useBlindedBlock, spec);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,21 @@ public class BlockProductionDuty implements Duty {
private final UInt64 slot;
private final ForkProvider forkProvider;
private final ValidatorApiChannel validatorApiChannel;
private final boolean useBlindedBlock;
private final Spec spec;

public BlockProductionDuty(
final Validator validator,
final UInt64 slot,
final ForkProvider forkProvider,
final ValidatorApiChannel validatorApiChannel,
final boolean useBlindedBlock,
final Spec spec) {
this.validator = validator;
this.slot = slot;
this.forkProvider = forkProvider;
this.validatorApiChannel = validatorApiChannel;
this.useBlindedBlock = useBlindedBlock;
this.spec = spec;
}

Expand Down Expand Up @@ -82,7 +85,7 @@ private SafeFuture<DutyResult> sendBlock(final SignedBeaconBlock signedBlock) {

public SafeFuture<Optional<BeaconBlock>> createUnsignedBlock(final BLSSignature randaoReveal) {
return validatorApiChannel.createUnsignedBlock(
slot, randaoReveal, validator.getGraffiti(), false);
slot, randaoReveal, validator.getGraffiti(), useBlindedBlock);
}

public SafeFuture<BLSSignature> createRandaoReveal(final ForkInfo forkInfo) {
Expand Down
Loading

0 comments on commit 6c816e2

Please sign in to comment.