Skip to content

Commit

Permalink
Alias cached beacon state (#3659)
Browse files Browse the repository at this point in the history
* Add alias for BeaconStateCached

* Move types to root file types

* Fix spec type

* Fix README import

* Remove duplicate import from README

* Rename BeaconStateCached to CachedBeaconState
  • Loading branch information
dapplion authored Jan 22, 2022
1 parent d9708a2 commit 7e1fb2f
Show file tree
Hide file tree
Showing 152 changed files with 650 additions and 766 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ jobs:
run: ./lodestar --version
- name: Check Types
run: yarn run check-types
- name: README check
run: yarn run check-readme
- name: Lint
run: yarn lint
- name: Unit tests
Expand All @@ -57,5 +59,3 @@ jobs:
run: yarn test:e2e
env:
GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL!=0 && secrets.GOERLI_RPC_URL || env.GOERLI_RPC_DEFAULT_URL }}
- name: README check
run: yarn run check-readme
11 changes: 4 additions & 7 deletions packages/beacon-state-transition/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,22 @@ The beacon state transition and state transition utilities
## Usage

```typescript

import {CachedBeaconState, stateTransition} from "@chainsafe/lodestar-beacon-state-transition/src/allForks";
import {allForks} from "@chainsafe/lodestar-types";
import {CachedBeaconStateAllForks, allForks} from "@chainsafe/lodestar-beacon-state-transition";
import {generateEmptySignedBlock} from "../test/utils/block";
import {generateState} from "../test/utils/state";

// dummy test state
const state: CachedBeaconState<allForks.BeaconState> = generateState() as CachedBeaconState<allForks.BeaconState>;
const state: CachedBeaconStateAllForks = generateState() as CachedBeaconStateAllForks;

// dummy test block
// dummy test block
const block: allForks.SignedBeaconBlock = generateEmptySignedBlock();

let postStateContext: allForks.BeaconState;
try {
postStateContext = stateTransition(state, block);
postStateContext = allForks.stateTransition(state, block);
} catch (e) {
console.log(e);
}

```

## License
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {FAR_FUTURE_EPOCH} from "@chainsafe/lodestar-params";
import {allForks, phase0} from "@chainsafe/lodestar-types";
import {CachedBeaconState} from "../util";
import {phase0} from "@chainsafe/lodestar-types";
import {CachedBeaconStateAllForks} from "../../types";

/**
* Initiate the exit of the validator with index ``index``.
Expand All @@ -22,10 +22,7 @@ import {CachedBeaconState} from "../util";
* ```
* Forcing consumers to pass the SubTree of `validator` directly mitigates this issue.
*/
export function initiateValidatorExit(
state: CachedBeaconState<allForks.BeaconState>,
validator: phase0.Validator
): void {
export function initiateValidatorExit(state: CachedBeaconStateAllForks, validator: phase0.Validator): void {
const {config, epochCtx} = state;

// return if validator already initiated exit
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {readonlyValues} from "@chainsafe/ssz";
import {MAX_VALIDATORS_PER_COMMITTEE} from "@chainsafe/lodestar-params";
import {allForks, phase0} from "@chainsafe/lodestar-types";
import {CachedBeaconState} from "../util";
import {phase0} from "@chainsafe/lodestar-types";
import {CachedBeaconStateAllForks} from "../../types";
import {verifyIndexedAttestationSignature} from "../signatureSets";

/**
* Check if `indexedAttestation` has sorted and unique indices and a valid aggregate signature.
*/
export function isValidIndexedAttestation(
state: CachedBeaconState<allForks.BeaconState>,
state: CachedBeaconStateAllForks,
indexedAttestation: phase0.IndexedAttestation,
verifySignature = true
): boolean {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {allForks, phase0} from "@chainsafe/lodestar-types";
import {phase0} from "@chainsafe/lodestar-types";
import {ForkName} from "@chainsafe/lodestar-params";

import {isSlashableValidator, isSlashableAttestationData, getAttesterSlashableIndices} from "../../util";
import {CachedBeaconState} from "../util";
import {CachedBeaconStateAllForks} from "../../types";
import {isValidIndexedAttestation} from "./isValidIndexedAttestation";
import {slashValidatorAllForks} from "./slashValidator";

Expand All @@ -14,11 +14,11 @@ import {slashValidatorAllForks} from "./slashValidator";
*/
export function processAttesterSlashing(
fork: ForkName,
state: CachedBeaconState<allForks.BeaconState>,
state: CachedBeaconStateAllForks,
attesterSlashing: phase0.AttesterSlashing,
verifySignatures = true
): void {
assertValidAttesterSlashing(state as CachedBeaconState<allForks.BeaconState>, attesterSlashing, verifySignatures);
assertValidAttesterSlashing(state as CachedBeaconStateAllForks, attesterSlashing, verifySignatures);

const intersectingIndices = getAttesterSlashableIndices(attesterSlashing);

Expand All @@ -38,7 +38,7 @@ export function processAttesterSlashing(
}

export function assertValidAttesterSlashing(
state: CachedBeaconState<allForks.BeaconState>,
state: CachedBeaconStateAllForks,
attesterSlashing: phase0.AttesterSlashing,
verifySignatures = true
): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {toHexString} from "@chainsafe/ssz";
import {allForks, ssz} from "@chainsafe/lodestar-types";
import {CachedBeaconState} from "../util";
import {CachedBeaconStateAllForks} from "../../types";
import {ZERO_HASH} from "../../constants";

/**
Expand All @@ -9,7 +9,7 @@ import {ZERO_HASH} from "../../constants";
* PERF: Fixed work independent of block contents.
* NOTE: `block` body root MUST be pre-cached.
*/
export function processBlockHeader(state: CachedBeaconState<allForks.BeaconState>, block: allForks.BeaconBlock): void {
export function processBlockHeader(state: CachedBeaconStateAllForks, block: allForks.BeaconBlock): void {
const slot = state.slot;
// verify that the slots match
if (block.slot !== slot) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import bls, {CoordType} from "@chainsafe/bls";
import {allForks, altair, phase0, ssz} from "@chainsafe/lodestar-types";
import {phase0, ssz} from "@chainsafe/lodestar-types";
import {verifyMerkleBranch} from "@chainsafe/lodestar-utils";
import {
DEPOSIT_CONTRACT_TREE_DEPTH,
Expand All @@ -12,19 +12,15 @@ import {

import {ZERO_HASH} from "../../constants";
import {computeDomain, computeSigningRoot, increaseBalance} from "../../util";
import {CachedBeaconState} from "../../allForks/util";
import {CachedBeaconStateAllForks, CachedBeaconStateAltair} from "../../types";

/**
* Process a Deposit operation. Potentially adds a new validator to the registry. Mutates the validators and balances
* trees, pushing contigious values at the end.
*
* PERF: Work depends on number of Deposit per block. On regular networks the average is 0 / block.
*/
export function processDeposit(
fork: ForkName,
state: CachedBeaconState<allForks.BeaconState>,
deposit: phase0.Deposit
): void {
export function processDeposit(fork: ForkName, state: CachedBeaconStateAllForks, deposit: phase0.Deposit): void {
const {config, validators, epochCtx} = state;
// verify the merkle branch
if (
Expand Down Expand Up @@ -87,7 +83,7 @@ export function processDeposit(

// Forks: altair, bellatrix, and future
if (fork !== ForkName.phase0) {
(state as CachedBeaconState<altair.BeaconState>).inactivityScores.push(0);
(state as CachedBeaconStateAltair).inactivityScores.push(0);
}

// now that there is a new validator, update the epoch context with the new pubkey
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import {EPOCHS_PER_ETH1_VOTING_PERIOD, SLOTS_PER_EPOCH} from "@chainsafe/lodestar-params";
import {allForks, phase0, ssz} from "@chainsafe/lodestar-types";
import {readonlyValues} from "@chainsafe/ssz";

import {CachedBeaconState} from "../util";
import {CachedBeaconStateAllForks} from "../../types";

/**
* Store vote counts for every eth1 block that has votes; if any eth1 block wins majority support within a 1024-slot
Expand All @@ -12,7 +11,7 @@ import {CachedBeaconState} from "../util";
* - Best case: Vote is already decided, zero work. See getNewEth1Data conditions
* - Worst case: 1023 votes and no majority vote yet.
*/
export function processEth1Data(state: CachedBeaconState<allForks.BeaconState>, body: allForks.BeaconBlockBody): void {
export function processEth1Data(state: CachedBeaconStateAllForks, body: allForks.BeaconBlockBody): void {
const newEth1Data = getNewEth1Data(state, body.eth1Data);
if (newEth1Data) {
state.eth1Data = body.eth1Data;
Expand All @@ -25,10 +24,7 @@ export function processEth1Data(state: CachedBeaconState<allForks.BeaconState>,
* Returns `newEth1Data` if adding the given `eth1Data` to `state.eth1DataVotes` would
* result in a change to `state.eth1Data`.
*/
export function getNewEth1Data(
state: CachedBeaconState<allForks.BeaconState>,
newEth1Data: phase0.Eth1Data
): phase0.Eth1Data | null {
export function getNewEth1Data(state: CachedBeaconStateAllForks, newEth1Data: phase0.Eth1Data): phase0.Eth1Data | null {
const SLOTS_PER_ETH1_VOTING_PERIOD = EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH;

// If there are not more than 50% votes, then we do not have to count to find a winner.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {allForks, phase0, ssz} from "@chainsafe/lodestar-types";
import {phase0, ssz} from "@chainsafe/lodestar-types";
import {ForkName} from "@chainsafe/lodestar-params";
import {isSlashableValidator} from "../../util";
import {CachedBeaconState} from "../../allForks/util";
import {CachedBeaconStateAllForks} from "../../types";
import {getProposerSlashingSignatureSets} from "../../allForks/signatureSets";
import {slashValidatorAllForks} from "../../allForks/block/slashValidator";
import {verifySignatureSet} from "../../util/signatureSets";
Expand All @@ -14,17 +14,17 @@ import {verifySignatureSet} from "../../util/signatureSets";
*/
export function processProposerSlashing(
fork: ForkName,
state: CachedBeaconState<allForks.BeaconState>,
state: CachedBeaconStateAllForks,
proposerSlashing: phase0.ProposerSlashing,
verifySignatures = true
): void {
assertValidProposerSlashing(state as CachedBeaconState<allForks.BeaconState>, proposerSlashing, verifySignatures);
assertValidProposerSlashing(state as CachedBeaconStateAllForks, proposerSlashing, verifySignatures);

slashValidatorAllForks(fork, state, proposerSlashing.signedHeader1.message.proposerIndex);
}

export function assertValidProposerSlashing(
state: CachedBeaconState<allForks.BeaconState>,
state: CachedBeaconStateAllForks,
proposerSlashing: phase0.ProposerSlashing,
verifySignatures = true
): void {
Expand Down Expand Up @@ -59,7 +59,7 @@ export function assertValidProposerSlashing(
// verify signatures
if (verifySignatures) {
for (const [i, signatureSet] of getProposerSlashingSignatureSets(
state as CachedBeaconState<allForks.BeaconState>,
state as CachedBeaconStateAllForks,
proposerSlashing
).entries()) {
if (!verifySignatureSet(signatureSet)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {hash} from "@chainsafe/ssz";
import {allForks} from "@chainsafe/lodestar-types";
import {getRandaoMix} from "../../util";
import {verifyRandaoSignature} from "../signatureSets";
import {CachedBeaconState} from "../util";
import {CachedBeaconStateAllForks} from "../../types";
import {EPOCHS_PER_HISTORICAL_VECTOR} from "@chainsafe/lodestar-params";

/**
Expand All @@ -12,7 +12,7 @@ import {EPOCHS_PER_HISTORICAL_VECTOR} from "@chainsafe/lodestar-params";
* PERF: Fixed work independent of block contents.
*/
export function processRandao(
state: CachedBeaconState<allForks.BeaconState>,
state: CachedBeaconStateAllForks,
block: allForks.BeaconBlock,
verifySignature = true
): void {
Expand All @@ -22,7 +22,7 @@ export function processRandao(

// verify RANDAO reveal
if (verifySignature) {
if (!verifyRandaoSignature(state as CachedBeaconState<allForks.BeaconState>, block)) {
if (!verifyRandaoSignature(state as CachedBeaconStateAllForks, block)) {
throw new Error("RANDAO reveal is an invalid signature");
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {FAR_FUTURE_EPOCH} from "@chainsafe/lodestar-params";
import {allForks, phase0} from "@chainsafe/lodestar-types";
import {phase0} from "@chainsafe/lodestar-types";
import {isActiveValidator} from "../../util";
import {CachedBeaconState} from "../../allForks/util";
import {CachedBeaconStateAllForks} from "../../types";
import {initiateValidatorExit} from "../../allForks/block";
import {verifyVoluntaryExitSignature} from "../../allForks/signatureSets";

Expand All @@ -11,20 +11,20 @@ import {verifyVoluntaryExitSignature} from "../../allForks/signatureSets";
* PERF: Work depends on number of VoluntaryExit per block. On regular networks the average is 0 / block.
*/
export function processVoluntaryExitAllForks(
state: CachedBeaconState<allForks.BeaconState>,
state: CachedBeaconStateAllForks,
signedVoluntaryExit: phase0.SignedVoluntaryExit,
verifySignature = true
): void {
if (!isValidVoluntaryExit(state as CachedBeaconState<allForks.BeaconState>, signedVoluntaryExit, verifySignature)) {
if (!isValidVoluntaryExit(state as CachedBeaconStateAllForks, signedVoluntaryExit, verifySignature)) {
throw Error("Invalid voluntary exit");
}

const validator = state.validators[signedVoluntaryExit.message.validatorIndex];
initiateValidatorExit(state as CachedBeaconState<allForks.BeaconState>, validator);
initiateValidatorExit(state as CachedBeaconStateAllForks, validator);
}

export function isValidVoluntaryExit(
state: CachedBeaconState<allForks.BeaconState>,
state: CachedBeaconStateAllForks,
signedVoluntaryExit: phase0.SignedVoluntaryExit,
verifySignature = true
): boolean {
Expand All @@ -43,7 +43,6 @@ export function isValidVoluntaryExit(
// verify the validator had been active long enough
currentEpoch >= validator.activationEpoch + config.SHARD_COMMITTEE_PERIOD &&
// verify signature
(!verifySignature ||
verifyVoluntaryExitSignature(state as CachedBeaconState<allForks.BeaconState>, signedVoluntaryExit))
(!verifySignature || verifyVoluntaryExitSignature(state as CachedBeaconStateAllForks, signedVoluntaryExit))
);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {allForks, ValidatorIndex} from "@chainsafe/lodestar-types";
import {ValidatorIndex} from "@chainsafe/lodestar-types";
import {
EPOCHS_PER_SLASHINGS_VECTOR,
ForkName,
Expand All @@ -12,12 +12,12 @@ import {
} from "@chainsafe/lodestar-params";

import {decreaseBalance, increaseBalance} from "../../util";
import {CachedBeaconState} from "../util";
import {initiateValidatorExit} from ".";
import {CachedBeaconStateAllForks} from "../../types";
import {initiateValidatorExit} from "./initiateValidatorExit";

export function slashValidatorAllForks(
fork: ForkName,
state: CachedBeaconState<allForks.BeaconState>,
state: CachedBeaconStateAllForks,
slashedIndex: ValidatorIndex,
whistleblowerIndex?: ValidatorIndex
): void {
Expand All @@ -26,7 +26,7 @@ export function slashValidatorAllForks(
const validator = state.validators[slashedIndex];

// TODO: Bellatrix initiateValidatorExit validators.update() with the one below
initiateValidatorExit(state as CachedBeaconState<allForks.BeaconState>, validator);
initiateValidatorExit(state as CachedBeaconStateAllForks, validator);

validator.slashed = true;
validator.withdrawableEpoch = Math.max(validator.withdrawableEpoch, epoch + EPOCHS_PER_SLASHINGS_VECTOR);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import {
HYSTERESIS_UPWARD_MULTIPLIER,
MAX_EFFECTIVE_BALANCE,
} from "@chainsafe/lodestar-params";
import {allForks} from "@chainsafe/lodestar-types";
import {IEpochProcess, CachedBeaconState} from "../util";
import {IEpochProcess, CachedBeaconStateAllForks} from "../../types";

/**
* Update effective balances if validator.balance has changed enough
Expand All @@ -18,10 +17,7 @@ import {IEpochProcess, CachedBeaconState} from "../util";
* - On normal mainnet conditions 0 validators change their effective balance
* - In case of big innactivity event a medium portion of validators may have their effectiveBalance updated
*/
export function processEffectiveBalanceUpdates(
state: CachedBeaconState<allForks.BeaconState>,
epochProcess: IEpochProcess
): void {
export function processEffectiveBalanceUpdates(state: CachedBeaconStateAllForks, epochProcess: IEpochProcess): void {
const HYSTERESIS_INCREMENT = EFFECTIVE_BALANCE_INCREMENT / HYSTERESIS_QUOTIENT;
const DOWNWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_DOWNWARD_MULTIPLIER;
const UPWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_UPWARD_MULTIPLIER;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import {EPOCHS_PER_ETH1_VOTING_PERIOD} from "@chainsafe/lodestar-params";
import {allForks, phase0} from "@chainsafe/lodestar-types";
import {phase0} from "@chainsafe/lodestar-types";
import {List} from "@chainsafe/ssz";
import {IEpochProcess, CachedBeaconState} from "../util";
import {IEpochProcess, CachedBeaconStateAllForks} from "../../types";

/**
* Reset eth1DataVotes tree every `EPOCHS_PER_ETH1_VOTING_PERIOD`.
*
* PERF: Almost no (constant) cost
*/
export function processEth1DataReset(
state: CachedBeaconState<allForks.BeaconState>,
epochProcess: IEpochProcess
): void {
export function processEth1DataReset(state: CachedBeaconStateAllForks, epochProcess: IEpochProcess): void {
const nextEpoch = epochProcess.currentEpoch + 1;

// reset eth1 data votes
Expand Down
Loading

0 comments on commit 7e1fb2f

Please sign in to comment.