Skip to content

Commit

Permalink
Apply proposer boost to first block in case of equivocation
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanBratanov committed Sep 19, 2023
1 parent db94bcc commit 52a0572
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ For information on changes in released versions of Teku, see the [releases page]
- The voluntary exit subcommand now accepts `--network=<NETWORK>` command line option, using it to load the network specification rather than loading configuration from the rest api, if specified.
- Add `/teku/v1/beacon/blob_sidecars/{slot}` Teku API which returns all blob sidecars (canonical and non-canonical) at a specific slot
- Updated LevelDb native library which is using LevelDb 1.23 using latest Snappy to 1.1.10 for compression (this change doesn't apply to Windows)
- Apply proposer boost to first block in case of equivocation ([spec PR](https://github.com/ethereum/consensus-specs/pull/3352))

### Bug Fixes
- When the rest-api's fail to start up they can now potentially 'fail fast' rather than silently ignoring the issue.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class Eth2NetworkConfiguration {
private static final int DEFAULT_STARTUP_TIMEOUT_SECONDS = 30;

public static final boolean DEFAULT_FORK_CHOICE_UPDATE_HEAD_ON_BLOCK_IMPORT_ENABLED = false;
public static final boolean DEFAULT_FORK_CHOICE_PROPOSER_BOOST_UNIQUENESS_ENABLED = true;

public static final String INITIAL_STATE_URL_PATH = "eth/v2/debug/beacon/states/finalized";
// 26 thousand years should be enough
Expand All @@ -70,6 +71,7 @@ public class Eth2NetworkConfiguration {
private final Optional<String> trustedSetup;

private final boolean forkChoiceUpdateHeadOnBlockImportEnabled;
private final boolean forkChoiceProposerBoostUniquenessEnabled;
private final Optional<Bytes32> terminalBlockHashOverride;
private final Optional<UInt256> totalTerminalDifficultyOverride;
private final Optional<UInt64> terminalBlockHashEpochOverride;
Expand All @@ -89,6 +91,7 @@ private Eth2NetworkConfiguration(
final Optional<UInt64> eth1DepositContractDeployBlock,
final Optional<String> trustedSetup,
final boolean forkChoiceUpdateHeadOnBlockImportEnabled,
final boolean forkChoiceProposerBoostUniquenessEnabled,
final Optional<UInt64> altairForkEpoch,
final Optional<UInt64> bellatrixForkEpoch,
final Optional<UInt64> capellaForkEpoch,
Expand Down Expand Up @@ -117,6 +120,7 @@ private Eth2NetworkConfiguration(
this.eth1DepositContractDeployBlock = eth1DepositContractDeployBlock;
this.trustedSetup = trustedSetup;
this.forkChoiceUpdateHeadOnBlockImportEnabled = forkChoiceUpdateHeadOnBlockImportEnabled;
this.forkChoiceProposerBoostUniquenessEnabled = forkChoiceProposerBoostUniquenessEnabled;
this.terminalBlockHashOverride = terminalBlockHashOverride;
this.totalTerminalDifficultyOverride = totalTerminalDifficultyOverride;
this.terminalBlockHashEpochOverride = terminalBlockHashEpochOverride;
Expand Down Expand Up @@ -189,6 +193,10 @@ public boolean isForkChoiceUpdateHeadOnBlockImportEnabled() {
return forkChoiceUpdateHeadOnBlockImportEnabled;
}

public boolean isForkChoiceProposerBoostUniquenessEnabled() {
return forkChoiceProposerBoostUniquenessEnabled;
}

public Optional<UInt64> getForkEpoch(final SpecMilestone specMilestone) {
return switch (specMilestone) {
case ALTAIR -> altairForkEpoch;
Expand Down Expand Up @@ -248,6 +256,8 @@ public static class Builder {
private Spec spec;
private boolean forkChoiceUpdateHeadOnBlockImportEnabled =
DEFAULT_FORK_CHOICE_UPDATE_HEAD_ON_BLOCK_IMPORT_ENABLED;
private boolean forkChoiceProposerBoostUniquenessEnabled =
DEFAULT_FORK_CHOICE_PROPOSER_BOOST_UNIQUENESS_ENABLED;

public void spec(Spec spec) {
this.spec = spec;
Expand Down Expand Up @@ -310,6 +320,7 @@ public Eth2NetworkConfiguration build() {
eth1DepositContractDeployBlock,
trustedSetup,
forkChoiceUpdateHeadOnBlockImportEnabled,
forkChoiceProposerBoostUniquenessEnabled,
altairForkEpoch,
bellatrixForkEpoch,
capellaForkEpoch,
Expand Down Expand Up @@ -415,6 +426,12 @@ public Builder forkChoiceUpdateHeadOnBlockImportEnabled(
return this;
}

public Builder forkChoiceProposerBoostUniquenessEnabled(
final boolean forkChoiceProposerBoostUniquenessEnabled) {
this.forkChoiceProposerBoostUniquenessEnabled = forkChoiceProposerBoostUniquenessEnabled;
return this;
}

public Builder altairForkEpoch(final UInt64 altairForkEpoch) {
this.altairForkEpoch = Optional.of(altairForkEpoch);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public class ForkChoice implements ForkChoiceUpdatedResultSubscriber {
private final ForkChoiceNotifier forkChoiceNotifier;
private final MergeTransitionBlockValidator transitionBlockValidator;
private final boolean forkChoiceUpdateHeadOnBlockImportEnabled;
private final boolean forkChoiceProposerBoostUniquenessEnabled;
private final AttestationStateSelector attestationStateSelector;
private final DeferredAttestations deferredAttestations = new DeferredAttestations();

Expand All @@ -111,6 +112,7 @@ public ForkChoice(
final TickProcessor tickProcessor,
final MergeTransitionBlockValidator transitionBlockValidator,
final boolean forkChoiceUpdateHeadOnBlockImportEnabled,
final boolean forkChoiceProposerBoostUniquenessEnabled,
final MetricsSystem metricsSystem) {
this.spec = spec;
this.forkChoiceExecutor = forkChoiceExecutor;
Expand All @@ -123,6 +125,7 @@ public ForkChoice(
new AttestationStateSelector(spec, recentChainData, metricsSystem);
this.tickProcessor = tickProcessor;
this.forkChoiceUpdateHeadOnBlockImportEnabled = forkChoiceUpdateHeadOnBlockImportEnabled;
this.forkChoiceProposerBoostUniquenessEnabled = forkChoiceProposerBoostUniquenessEnabled;
recentChainData.subscribeStoreInitialized(this::initializeProtoArrayForkChoice);
forkChoiceNotifier.subscribeToForkChoiceUpdatedResult(this);
}
Expand Down Expand Up @@ -150,6 +153,7 @@ public ForkChoice(
new TickProcessor(spec, recentChainData),
transitionBlockValidator,
true,
true,
metricsSystem);
}

Expand Down Expand Up @@ -488,23 +492,20 @@ private BlockImportResult importBlockAndState(
}

switch (blobSidecarsAndValidationResult.getValidationResult()) {
case VALID:
case NOT_REQUIRED:
LOG.debug(
"blobSidecars validation result: {}", blobSidecarsAndValidationResult::toLogString);

break;
case NOT_AVAILABLE:
case VALID, NOT_REQUIRED -> LOG.debug(
"blobSidecars validation result: {}", blobSidecarsAndValidationResult::toLogString);
case NOT_AVAILABLE -> {
LOG.warn(
"blobSidecars validation result: {}", blobSidecarsAndValidationResult::toLogString);
return BlockImportResult.failedDataAvailabilityCheckNotAvailable(
blobSidecarsAndValidationResult.getCause());

case INVALID:
}
case INVALID -> {
LOG.error(
"blobSidecars validation result: {}", blobSidecarsAndValidationResult::toLogString);
return BlockImportResult.failedDataAvailabilityCheckInvalid(
blobSidecarsAndValidationResult.getCause());
}
}

final ForkChoiceStrategy forkChoiceStrategy = getForkChoiceStrategy();
Expand Down Expand Up @@ -542,13 +543,8 @@ private BlockImportResult importBlockAndState(
blobSidecars,
earliestBlobSidecarsSlot);

if (spec.getCurrentSlot(transaction).equals(block.getSlot())) {
final UInt64 millisPerSlot = spec.getMillisPerSlot(block.getSlot());
final UInt64 timeIntoSlotMillis = getMillisIntoSlot(transaction, millisPerSlot);

if (isBeforeAttestingInterval(millisPerSlot, timeIntoSlotMillis)) {
transaction.setProposerBoostRoot(block.getRoot());
}
if (applyProposerBoost(block, transaction)) {
transaction.setProposerBoostRoot(block.getRoot());
}

blockImportPerformance.ifPresent(BlockImportPerformance::transactionReady);
Expand Down Expand Up @@ -582,6 +578,22 @@ private BlockImportResult importBlockAndState(
return result;
}

private boolean applyProposerBoost(
final SignedBeaconBlock block, final StoreTransaction transaction) {
if (spec.getCurrentSlot(transaction).equals(block.getSlot())) {
final UInt64 millisPerSlot = spec.getMillisPerSlot(block.getSlot());
final UInt64 timeIntoSlotMillis = getMillisIntoSlot(transaction, millisPerSlot);

if (isBeforeAttestingInterval(millisPerSlot, timeIntoSlotMillis)) {
if (forkChoiceProposerBoostUniquenessEnabled) {
return transaction.getProposerBoostRoot().isEmpty();
}
return true;
}
}
return false;
}

/**
* In order to keep track of DataAvailability Window, we need to compute the earliest slot we can
* consider data available for the given block. It needs to take in account possible empty slots
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import static tech.pegasys.teku.infrastructure.async.SafeFutureAssert.safeJoin;
import static tech.pegasys.teku.infrastructure.unsigned.UInt64.ONE;
import static tech.pegasys.teku.infrastructure.unsigned.UInt64.ZERO;
import static tech.pegasys.teku.networks.Eth2NetworkConfiguration.DEFAULT_FORK_CHOICE_PROPOSER_BOOST_UNIQUENESS_ENABLED;
import static tech.pegasys.teku.networks.Eth2NetworkConfiguration.DEFAULT_FORK_CHOICE_UPDATE_HEAD_ON_BLOCK_IMPORT_ENABLED;
import static tech.pegasys.teku.statetransition.forkchoice.ForkChoice.BLOCK_CREATION_TOLERANCE_MS;

Expand Down Expand Up @@ -154,6 +155,7 @@ private void setupWithSpec(final Spec spec) {
new TickProcessor(spec, recentChainData),
transitionBlockValidator,
DEFAULT_FORK_CHOICE_UPDATE_HEAD_ON_BLOCK_IMPORT_ENABLED,
DEFAULT_FORK_CHOICE_PROPOSER_BOOST_UNIQUENESS_ENABLED,
metricsSystem);

// Starting and mocks
Expand Down Expand Up @@ -303,6 +305,7 @@ void onBlock_shouldReorgWhenProposerWeightingMakesForkBestChain(
new TickProcessor(spec, recentChainData),
transitionBlockValidator,
DEFAULT_FORK_CHOICE_UPDATE_HEAD_ON_BLOCK_IMPORT_ENABLED,
DEFAULT_FORK_CHOICE_PROPOSER_BOOST_UNIQUENESS_ENABLED,
metricsSystem);

final UInt64 currentSlot = recentChainData.getCurrentSlot().orElseThrow();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@ protected void initForkChoice() {
new TickProcessor(spec, recentChainData),
new MergeTransitionBlockValidator(spec, recentChainData, executionLayer),
beaconConfig.eth2NetworkConfig().isForkChoiceUpdateHeadOnBlockImportEnabled(),
beaconConfig.eth2NetworkConfig().isForkChoiceProposerBoostUniquenessEnabled(),
metricsSystem);
forkChoiceTrigger = new ForkChoiceTrigger(forkChoice);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,19 @@ public class Eth2NetworkOptions {
private boolean forkChoiceUpdateHeadOnBlockImportEnabled =
Eth2NetworkConfiguration.DEFAULT_FORK_CHOICE_UPDATE_HEAD_ON_BLOCK_IMPORT_ENABLED;

// can be removed after all clients have rolled out the spec change:
// https://github.com/ethereum/consensus-specs/pull/3352
@Option(
names = {"--Xfork-choice-proposer-boost-uniqueness-enabled"},
paramLabel = "<BOOLEAN>",
description = "Apply proposer boost to first block in case of equivocation.",
arity = "0..1",
fallbackValue = "true",
showDefaultValue = Visibility.ALWAYS,
hidden = true)
private boolean forkChoiceProposerBoostUniquenessEnabled =
Eth2NetworkConfiguration.DEFAULT_FORK_CHOICE_PROPOSER_BOOST_UNIQUENESS_ENABLED;

@Option(
names = {"--Xeth1-deposit-contract-deploy-block-override"},
hidden = true,
Expand Down Expand Up @@ -246,6 +259,7 @@ private void configureEth2Network(Eth2NetworkConfiguration.Builder builder) {
builder
.safeSlotsToImportOptimistically(safeSlotsToImportOptimistically)
.forkChoiceUpdateHeadOnBlockImportEnabled(forkChoiceUpdateHeadOnBlockImportEnabled)
.forkChoiceProposerBoostUniquenessEnabled(forkChoiceProposerBoostUniquenessEnabled)
.epochsStoreBlobs(epochsStoreBlobs);
}

Expand Down

0 comments on commit 52a0572

Please sign in to comment.