Skip to content

Commit

Permalink
Added config items for late block reorg
Browse files Browse the repository at this point in the history
 - added  `REORG_HEAD_WEIGHT_THRESHOLD`, `REORG_PARENT_WEIGHT_THRESHOLD`, and  `REORG_MAX_EPOCHS_SINCE_FINALIZATION` to phase0 configuration, and defaulted

 - added utility functions:
   - `isShufflingStable`
   - `isFinalizationOk`
   - `calculateCommitteeFraction`

which were part of the changes in ethereum/consensus-specs#3034

partially addresses Consensys#6595

Signed-off-by: Paul Harris <[email protected]>
  • Loading branch information
rolfyone committed Nov 16, 2023
1 parent f158d1e commit d25ef6f
Show file tree
Hide file tree
Showing 19 changed files with 251 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ the [releases page](https://github.com/Consensys/teku/releases).
- By default, Teku won't allow syncing from genesis, users should use `--checkpoint-sync-url` when starting a new node. It is possible to revert back to the previous behaviour using the flag `--ignore-weak-subjectivity-period-enabled`.

### Additions and Improvements
- Added configuration attributes in support of honest validator late block reorg, which adds `REORG_HEAD_WEIGHT_THRESHOLD`, `REORG_PARENT_WEIGHT_THRESHOLD`, and `REORG_MAX_EPOCHS_SINCE_FINALIZATION` to phase 0 configurations. Mainnet values have been added as defaults for configurations that have not explicitly listed them.

### Bug Fixes
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,21 @@ public int getSafeSlotsToUpdateJustified() {
return specConfig.getSafeSlotsToUpdateJustified();
}

@Override
public int getReorgMaxEpochsSinceFinalization() {
return specConfig.getReorgMaxEpochsSinceFinalization();
}

@Override
public int getReorgHeadWeightThreshold() {
return specConfig.getReorgHeadWeightThreshold();
}

@Override
public int getReorgParentWeightThreshold() {
return specConfig.getReorgParentWeightThreshold();
}

@Override
public long getDepositChainId() {
return specConfig.getDepositChainId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ default int getMillisPerSlot() {
// Misc
int getSafeSlotsToUpdateJustified();

int getReorgMaxEpochsSinceFinalization();

int getReorgHeadWeightThreshold();

int getReorgParentWeightThreshold();

// Casters
default Optional<SpecConfigAltair> toVersionAltair() {
return Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ public class SpecConfigPhase0 implements SpecConfig {
private final int attestationSubnetCount;
private final int attestationSubnetExtraBits;
private final int attestationSubnetPrefixBits;
private final int reorgMaxEpochsSinceFinalization;

private final int reorgHeadWeightThreshold;
private final int reorgParentWeightThreshold;

public SpecConfigPhase0(
final Map<String, Object> rawConfig,
Expand Down Expand Up @@ -182,7 +186,10 @@ public SpecConfigPhase0(
final int subnetsPerNode,
final int attestationSubnetCount,
final int attestationSubnetExtraBits,
final int attestationSubnetPrefixBits) {
final int attestationSubnetPrefixBits,
final int reorgMaxEpochsSinceFinalization,
final int reorgHeadWeightThreshold,
final int reorgParentWeightThreshold) {
this.rawConfig = rawConfig;
this.eth1FollowDistance = eth1FollowDistance;
this.maxCommitteesPerSlot = maxCommitteesPerSlot;
Expand Down Expand Up @@ -249,6 +256,9 @@ public SpecConfigPhase0(
this.attestationSubnetCount = attestationSubnetCount;
this.attestationSubnetExtraBits = attestationSubnetExtraBits;
this.attestationSubnetPrefixBits = attestationSubnetPrefixBits;
this.reorgMaxEpochsSinceFinalization = reorgMaxEpochsSinceFinalization;
this.reorgHeadWeightThreshold = reorgHeadWeightThreshold;
this.reorgParentWeightThreshold = reorgParentWeightThreshold;
}

@Override
Expand Down Expand Up @@ -506,6 +516,21 @@ public int getSafeSlotsToUpdateJustified() {
return safeSlotsToUpdateJustified;
}

@Override
public int getReorgMaxEpochsSinceFinalization() {
return reorgMaxEpochsSinceFinalization;
}

@Override
public int getReorgHeadWeightThreshold() {
return reorgHeadWeightThreshold;
}

@Override
public int getReorgParentWeightThreshold() {
return reorgParentWeightThreshold;
}

@Override
public int getProposerScoreBoost() {
return proposerScoreBoost;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ public class SpecConfigBuilder {
private Integer attestationSubnetExtraBits;
private Integer attestationSubnetPrefixBits;

// added after Phase0, so add default values, or will be compatability issue
private Integer reorgMaxEpochsSinceFinalization = 2;

private Integer reorgHeadWeightThreshold = 20;

private Integer reorgParentWeightThreshold = 160;

private final BuilderChain<SpecConfig, SpecConfigDeneb> builderChain =
BuilderChain.create(new AltairBuilder())
.appendBuilder(new BellatrixBuilder())
Expand Down Expand Up @@ -203,7 +210,10 @@ public SpecConfig build() {
subnetsPerNode,
attestationSubnetCount,
attestationSubnetExtraBits,
attestationSubnetPrefixBits);
attestationSubnetPrefixBits,
reorgMaxEpochsSinceFinalization,
reorgHeadWeightThreshold,
reorgParentWeightThreshold);

return builderChain.build(config);
}
Expand Down Expand Up @@ -274,6 +284,9 @@ private Map<String, Object> getValidationMap() {
constants.put("attestationSubnetCount", attestationSubnetCount);
constants.put("attestationSubnetExtraBits", attestationSubnetExtraBits);
constants.put("attestationSubnetPrefixBits", attestationSubnetPrefixBits);
constants.put("reorgMaxEpochsSinceFinalization", reorgMaxEpochsSinceFinalization);
constants.put("reorgHeadWeightThreshold", reorgHeadWeightThreshold);
constants.put("reorgParentWeightThreshold", reorgParentWeightThreshold);
return constants;
}

Expand Down Expand Up @@ -677,6 +690,22 @@ public SpecConfigBuilder attestationSubnetPrefixBits(final Integer attestationSu
return this;
}

public SpecConfigBuilder reorgMaxEpochsSinceFinalization(
final Integer reorgMaxEpochsSinceFinalization) {
this.reorgMaxEpochsSinceFinalization = reorgMaxEpochsSinceFinalization;
return this;
}

public SpecConfigBuilder reorgHeadWeightThreshold(final Integer reorgHeadWeightThreshold) {
this.reorgHeadWeightThreshold = reorgHeadWeightThreshold;
return this;
}

public SpecConfigBuilder reorgParentWeightThreshold(final Integer reorgParentWeightThreshold) {
this.reorgParentWeightThreshold = reorgParentWeightThreshold;
return this;
}

public SpecConfigBuilder altairBuilder(final Consumer<AltairBuilder> consumer) {
builderChain.withBuilder(AltairBuilder.class, consumer);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,20 @@ public Bytes32 getSeed(BeaconState state, UInt64 epoch, Bytes4 domainType)
return Hash.sha256(domainType.getWrappedBytes(), epochBytes, mix);
}

/**
* calculate_committee_fraction Refer to fork-choice specification.
*
* @param beaconState
* @param committeePercent
* @return
*/
public UInt64 calculateCommitteeFraction(
final BeaconState beaconState, final UInt64 committeePercent) {
final UInt64 committeeWeight =
getTotalActiveBalance(beaconState).dividedBy(config.getSlotsPerEpoch());
return committeeWeight.times(committeePercent).dividedBy(100);
}

/**
* return the number of committees in each slot for the given `epoch`.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,27 @@ public NavigableMap<UInt64, Bytes32> getAncestorsOnFork(
return roots;
}

/**
* is_shuffling_stable
*
* <p>Refer to fork-choice specification.
*
* @param slot
* @return
*/
public boolean isShufflingStable(final UInt64 slot) {
return !slot.mod(specConfig.getSlotsPerEpoch()).isZero();
}

public boolean isFinalizationOk(final ReadOnlyStore store, final UInt64 slot) {
final UInt64 epochsSinceFinalization =
miscHelpers
.computeEpochAtSlot(slot)
.minusMinZero(store.getFinalizedCheckpoint().getEpoch());
return epochsSinceFinalization.isLessThanOrEqualTo(
specConfig.getReorgMaxEpochsSinceFinalization());
}

private void maybeAddRoot(
final UInt64 startSlot,
final UInt64 step,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ HYSTERESIS_UPWARD_MULTIPLIER: 5
# ---------------------------------------------------------------
# 2**3 (= 8)
SAFE_SLOTS_TO_UPDATE_JUSTIFIED: 8
# 20%
REORG_HEAD_WEIGHT_THRESHOLD: 20
# 160%
REORG_PARENT_WEIGHT_THRESHOLD: 160
# `2` epochs
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2
# Validator
# ---------------------------------------------------------------
# 2**10 (= 1024) ~1.4 hour
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ CHURN_LIMIT_QUOTIENT: 4096
# ---------------------------------------------------------------
# 40%
PROPOSER_SCORE_BOOST: 40

# 20%
REORG_HEAD_WEIGHT_THRESHOLD: 20
# 160%
REORG_PARENT_WEIGHT_THRESHOLD: 160
# `2` epochs
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2

# Deposit contract
# ---------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 8
# ---------------------------------------------------------------
# 40%
PROPOSER_SCORE_BOOST: 40
# 20%
REORG_HEAD_WEIGHT_THRESHOLD: 20
# 160%
REORG_PARENT_WEIGHT_THRESHOLD: 160
# `2` epochs
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2

# Deposit contract
# ---------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ CHURN_LIMIT_QUOTIENT: 32
# ---------------------------------------------------------------
# 70%
PROPOSER_SCORE_BOOST: 70
# 20%
REORG_HEAD_WEIGHT_THRESHOLD: 20
# 160%
REORG_PARENT_WEIGHT_THRESHOLD: 160
# `2` epochs
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2


# Deposit contract
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ CAPELLA_FORK_EPOCH: 8100
# ---------------------------------------------------------------
# 40%
PROPOSER_SCORE_BOOST: 40
# 20%
REORG_HEAD_WEIGHT_THRESHOLD: 20
# 160%
REORG_PARENT_WEIGHT_THRESHOLD: 160
# `2` epochs
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2

# Time parameters
# ---------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 8
# ---------------------------------------------------------------
# 40%
PROPOSER_SCORE_BOOST: 40
# 20%
REORG_HEAD_WEIGHT_THRESHOLD: 20
# 160%
REORG_PARENT_WEIGHT_THRESHOLD: 160
# `2` epochs
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2

# Deposit contract
# ---------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,12 @@ MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 4
# ---------------------------------------------------------------
# 40%
PROPOSER_SCORE_BOOST: 40

# 20%
REORG_HEAD_WEIGHT_THRESHOLD: 20
# 160%
REORG_PARENT_WEIGHT_THRESHOLD: 160
# `2` epochs
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2

# Deposit contract
# ---------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,12 @@ CHURN_LIMIT_QUOTIENT: 65536
# ---------------------------------------------------------------
# 70%
PROPOSER_SCORE_BOOST: 70

# 20%
REORG_HEAD_WEIGHT_THRESHOLD: 20
# 160%
REORG_PARENT_WEIGHT_THRESHOLD: 160
# `2` epochs
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2

# Deposit contract
# ---------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ CHURN_LIMIT_QUOTIENT: 65536
# ---------------------------------------------------------------
# 40%
PROPOSER_SCORE_BOOST: 40
# 20%
REORG_HEAD_WEIGHT_THRESHOLD: 20
# 160%
REORG_PARENT_WEIGHT_THRESHOLD: 160
# `2` epochs
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2

# Deposit contract
# ---------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 8
# ---------------------------------------------------------------
# 70%
PROPOSER_SCORE_BOOST: 70
# 20%
REORG_HEAD_WEIGHT_THRESHOLD: 20
# 160%
REORG_PARENT_WEIGHT_THRESHOLD: 160
# `2` epochs
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2


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

package tech.pegasys.teku.spec.logic.common.helpers;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
Expand Down Expand Up @@ -129,6 +130,32 @@ public void getBeaconCommittee_stateIsNewerThanSlot() {
assertDoesNotThrow(() -> beaconStateAccessors.getBeaconCommittee(state, oldSlot, ONE));
}

@Test
void calculateCommitteeFraction_full() {
final BeaconState state = dataStructureUtil.randomBeaconState(1024);
final UInt64 totalActiveBalance =
spec.atSlot(state.getSlot()).beaconStateAccessors().getTotalActiveBalance(state);
final UInt64 totalActiveBalancePerSlot =
totalActiveBalance.dividedBy(spec.getGenesisSpec().getSlotsPerEpoch());
final UInt64 fraction =
beaconStateAccessors.calculateCommitteeFraction(state, UInt64.valueOf(100));
// at its simplest, if we've divided by slots in the function, this should be
// totalActiveBalance/slots (because fraction is 100%)
assertThat(fraction).isEqualTo(totalActiveBalancePerSlot);
}

@Test
void calculateCommitteeFraction_minimal() {
final BeaconState state = dataStructureUtil.randomBeaconState(1024);
final UInt64 totalActiveBalance =
spec.atSlot(state.getSlot()).beaconStateAccessors().getTotalActiveBalance(state);
final UInt64 totalActiveBalancePerSlot =
totalActiveBalance.dividedBy(spec.getGenesisSpec().getSlotsPerEpoch());
final UInt64 fraction = beaconStateAccessors.calculateCommitteeFraction(state, UInt64.ONE);
// should be 1% of balance per slot...
assertThat(fraction).isEqualTo(totalActiveBalancePerSlot.dividedBy(100));
}

private BeaconState createBeaconState() {
return new BeaconStateTestBuilder(dataStructureUtil)
.forkVersion(specConfig.getGenesisForkVersion())
Expand Down
Loading

0 comments on commit d25ef6f

Please sign in to comment.