Skip to content

Commit

Permalink
Move shufflings code together into seed util (#3710)
Browse files Browse the repository at this point in the history
  • Loading branch information
dapplion authored Feb 7, 2022
1 parent 7f37195 commit 6ebae5c
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 75 deletions.
31 changes: 3 additions & 28 deletions packages/beacon-state-transition/src/allForks/util/epochContext.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {ByteVector, hash, BitList, List, readonlyValuesListOfLeafNodeStruct} from "@chainsafe/ssz";
import {ByteVector, BitList, List, readonlyValuesListOfLeafNodeStruct} from "@chainsafe/ssz";
import bls, {CoordType, PublicKey} from "@chainsafe/bls";
import {
BLSSignature,
Expand All @@ -14,7 +14,6 @@ import {
import {IBeaconConfig} from "@chainsafe/lodestar-config";
import {
BASE_REWARD_FACTOR,
DOMAIN_BEACON_PROPOSER,
EFFECTIVE_BALANCE_INCREMENT,
FAR_FUTURE_EPOCH,
GENESIS_EPOCH,
Expand All @@ -24,16 +23,15 @@ import {
SYNC_REWARD_WEIGHT,
WEIGHT_DENOMINATOR,
} from "@chainsafe/lodestar-params";
import {bigIntSqrt, intToBytes, LodestarError} from "@chainsafe/lodestar-utils";
import {bigIntSqrt, LodestarError} from "@chainsafe/lodestar-utils";
import {MutableVector} from "@chainsafe/persistent-ts";

import {
computeActivationExitEpoch,
computeEpochAtSlot,
computeProposerIndex,
computeProposers,
computeStartSlotAtEpoch,
getChurnLimit,
getSeed,
isActiveValidator,
isAggregatorFromCommitteeLength,
zipIndexesCommitteeBits,
Expand Down Expand Up @@ -269,29 +267,6 @@ export function syncPubkeys(
}
}

/**
* Compute proposer indices for an epoch
*/
export function computeProposers(
state: allForks.BeaconState,
shuffling: IEpochShuffling,
effectiveBalances: MutableVector<number>
): number[] {
const epochSeed = getSeed(state, shuffling.epoch, DOMAIN_BEACON_PROPOSER);
const startSlot = computeStartSlotAtEpoch(shuffling.epoch);
const proposers = [];
for (let slot = startSlot; slot < startSlot + SLOTS_PER_EPOCH; slot++) {
proposers.push(
computeProposerIndex(
effectiveBalances,
shuffling.activeIndices,
hash(Buffer.concat([epochSeed, intToBytes(slot, 8)]))
)
);
}
return proposers;
}

/**
* Same logic in https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.5/specs/altair/beacon-chain.md#sync-committee-processing
*/
Expand Down
1 change: 0 additions & 1 deletion packages/beacon-state-transition/src/util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export * from "./domain";
export * from "./epoch";
export * from "./genesis";
export * from "./interop";
export * from "./proposer";
export * from "./seed";
export * from "./shuffle";
export * from "./shufflingDecisionRoot";
Expand Down
43 changes: 0 additions & 43 deletions packages/beacon-state-transition/src/util/proposer.ts

This file was deleted.

76 changes: 74 additions & 2 deletions packages/beacon-state-transition/src/util/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,81 @@
*/

import {hash} from "@chainsafe/ssz";
import {Epoch, Bytes32, DomainType, allForks} from "@chainsafe/lodestar-types";
import {Epoch, Bytes32, DomainType, allForks, ValidatorIndex} from "@chainsafe/lodestar-types";
import {assert, bytesToBigInt, intToBytes} from "@chainsafe/lodestar-utils";
import {EPOCHS_PER_HISTORICAL_VECTOR, MIN_SEED_LOOKAHEAD, SHUFFLE_ROUND_COUNT} from "@chainsafe/lodestar-params";
import {
DOMAIN_BEACON_PROPOSER,
EPOCHS_PER_HISTORICAL_VECTOR,
MAX_EFFECTIVE_BALANCE,
MIN_SEED_LOOKAHEAD,
SHUFFLE_ROUND_COUNT,
SLOTS_PER_EPOCH,
} from "@chainsafe/lodestar-params";
import {IEpochShuffling} from "../allForks";
import {MutableVector} from "@chainsafe/persistent-ts";
import {computeStartSlotAtEpoch} from "./epoch";

/**
* Compute proposer indices for an epoch
*/
export function computeProposers(
state: allForks.BeaconState,
shuffling: IEpochShuffling,
effectiveBalances: MutableVector<number>
): number[] {
const epochSeed = getSeed(state, shuffling.epoch, DOMAIN_BEACON_PROPOSER);
const startSlot = computeStartSlotAtEpoch(shuffling.epoch);
const proposers = [];
for (let slot = startSlot; slot < startSlot + SLOTS_PER_EPOCH; slot++) {
proposers.push(
computeProposerIndex(
effectiveBalances,
shuffling.activeIndices,
hash(Buffer.concat([epochSeed, intToBytes(slot, 8)]))
)
);
}
return proposers;
}

/**
* Return from ``indices`` a random index sampled by effective balance.
*
* SLOW CODE - 🐢
*/
export function computeProposerIndex(
effectiveBalances: MutableVector<number>,
indices: ValidatorIndex[],
seed: Uint8Array
): ValidatorIndex {
assert.gt(indices.length, 0, "Validator indices must not be empty");

// TODO: Inline outside this function
const MAX_RANDOM_BYTE = 2 ** 8 - 1;

let i = 0;
/* eslint-disable-next-line no-constant-condition */
while (true) {
const candidateIndex = indices[computeShuffledIndex(i % indices.length, indices.length, seed)];
const randByte = hash(
Buffer.concat([
seed,
//
intToBytes(Math.floor(i / 32), 8),
])
)[i % 32];

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const effectiveBalance = effectiveBalances.get(candidateIndex)!;
if (effectiveBalance * MAX_RANDOM_BYTE >= MAX_EFFECTIVE_BALANCE * randByte) {
return candidateIndex;
}
i += 1;
if (i === indices.length) {
return -1;
}
}
}

/**
* Return the shuffled validator index corresponding to ``seed`` (and ``index_count``).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import {itBench} from "@dapplion/benchmark";
import {Epoch} from "@chainsafe/lodestar-types";
import {computeEpochAtSlot, CachedBeaconStateAllForks} from "../../../../src";
import {computeEpochShuffling, computeProposers} from "../../../../src/allForks";
import {computeEpochShuffling} from "../../../../src/allForks";
import {generatePerfTestCachedStatePhase0, numValidators} from "../../util";
import {getNextSyncCommittee} from "../../../../src/altair/util/syncCommittee";
import {computeProposers} from "../../../../src/util/seed";

describe("epoch shufflings", () => {
let state: CachedBeaconStateAllForks;
Expand Down

0 comments on commit 6ebae5c

Please sign in to comment.