Skip to content

Commit

Permalink
Make BeaconChain dependencies readonly (#4376)
Browse files Browse the repository at this point in the history
* Update tests with BeaconChain deps readonly

* Make BeaconChain dependencies readonly
  • Loading branch information
dapplion committed Aug 7, 2022
1 parent 1da9558 commit ac5398e
Show file tree
Hide file tree
Showing 16 changed files with 62 additions and 37 deletions.
14 changes: 7 additions & 7 deletions packages/beacon-node/src/chain/chain.ts
Expand Up @@ -66,13 +66,13 @@ export class BeaconChain implements IBeaconChain {
readonly config: IBeaconConfig;
readonly anchorStateLatestBlockSlot: Slot;

bls: IBlsVerifier;
forkChoice: IForkChoice;
clock: IBeaconClock;
emitter: ChainEventEmitter;
stateCache: StateContextCache;
checkpointStateCache: CheckpointStateCache;
regen: IStateRegenerator;
readonly bls: IBlsVerifier;
readonly forkChoice: IForkChoice;
readonly clock: IBeaconClock;
readonly emitter: ChainEventEmitter;
readonly stateCache: StateContextCache;
readonly checkpointStateCache: CheckpointStateCache;
readonly regen: IStateRegenerator;
readonly lightClientServer: LightClientServer;
readonly reprocessController: ReprocessController;

Expand Down
14 changes: 7 additions & 7 deletions packages/beacon-node/src/chain/interface.ts
Expand Up @@ -53,13 +53,13 @@ export interface IBeaconChain {
/** The initial slot that the chain is started with */
readonly anchorStateLatestBlockSlot: Slot;

bls: IBlsVerifier;
forkChoice: IForkChoice;
clock: IBeaconClock;
emitter: ChainEventEmitter;
stateCache: StateContextCache;
checkpointStateCache: CheckpointStateCache;
regen: IStateRegenerator;
readonly bls: IBlsVerifier;
readonly forkChoice: IForkChoice;
readonly clock: IBeaconClock;
readonly emitter: ChainEventEmitter;
readonly stateCache: StateContextCache;
readonly checkpointStateCache: CheckpointStateCache;
readonly regen: IStateRegenerator;
readonly lightClientServer: LightClientServer;
readonly reprocessController: ReprocessController;

Expand Down
Expand Up @@ -3,7 +3,6 @@ import chaiAsPromised from "chai-as-promised";
import sinon, {SinonStubbedInstance} from "sinon";
import {allForks} from "@lodestar/types";
import {getBeaconBlockApi} from "../../../../../../src/api/impl/beacon/blocks/index.js";
import {BeaconChain} from "../../../../../../src/chain/index.js";
import {Eth2Gossipsub} from "../../../../../../src/network/gossip/index.js";
import {generateEmptySignedBlock} from "../../../../../utils/block.js";
import {BeaconSync} from "../../../../../../src/sync/index.js";
Expand All @@ -14,7 +13,7 @@ use(chaiAsPromised);
describe("api - beacon - publishBlock", function () {
let gossipStub: SinonStubbedInstance<Eth2Gossipsub>;
let block: allForks.SignedBeaconBlock;
let chainStub: SinonStubbedInstance<BeaconChain>;
let chainStub: ApiImplTestModules["chainStub"];
let syncStub: SinonStubbedInstance<BeaconSync>;
let server: ApiImplTestModules;

Expand Down
5 changes: 2 additions & 3 deletions packages/beacon-node/test/unit/api/impl/debug/index.test.ts
Expand Up @@ -10,17 +10,16 @@ import {toHexString} from "@chainsafe/ssz";
import * as stateApiUtils from "../../../../../src/api/impl/beacon/state/utils.js";
import {getDebugApi} from "../../../../../src/api/impl/debug/index.js";
import {INetwork, Network} from "../../../../../src/network/index.js";
import {IBeaconChain} from "../../../../../src/chain/index.js";
import {generateProtoBlock} from "../../../../utils/block.js";
import {StubbedBeaconDb} from "../../../../utils/stub/index.js";
import {StubbedBeaconDb, StubbedChainMutable} from "../../../../utils/stub/index.js";
import {generateCachedAltairState, generateState} from "../../../../utils/state.js";
import {setupApiImplTestServer} from "../index.test.js";
import {SinonStubFn} from "../../../../utils/types.js";

// TODO remove stub
describe.skip("api - debug - beacon", function () {
let debugApi: ReturnType<typeof getDebugApi>;
let chainStub: SinonStubbedInstance<IBeaconChain>;
let chainStub: StubbedChainMutable<"forkChoice">;
let forkchoiceStub: SinonStubbedInstance<IForkChoice>;
let dbStub: StubbedBeaconDb;
let networkStub: SinonStubbedInstance<INetwork>;
Expand Down
5 changes: 3 additions & 2 deletions packages/beacon-node/test/unit/api/impl/events/events.test.ts
Expand Up @@ -2,16 +2,17 @@ import {expect} from "chai";
import sinon, {SinonStubbedInstance} from "sinon";
import {routes} from "@lodestar/api";
import {config} from "@lodestar/config/default";
import {BeaconChain, ChainEvent, ChainEventEmitter, IBeaconChain} from "../../../../../src/chain/index.js";
import {BeaconChain, ChainEvent, ChainEventEmitter} from "../../../../../src/chain/index.js";
import {getEventsApi} from "../../../../../src/api/impl/events/index.js";
import {generateProtoBlock, generateEmptySignedBlock, generateSignedBlock} from "../../../../utils/block.js";
import {generateAttestation, generateEmptySignedVoluntaryExit} from "../../../../utils/attestation.js";
import {generateCachedState} from "../../../../utils/state.js";
import {StateContextCache} from "../../../../../src/chain/stateCache/index.js";
import {StubbedChainMutable} from "../../../../utils/stub/index.js";

describe("Events api impl", function () {
describe("beacon event stream", function () {
let chainStub: SinonStubbedInstance<IBeaconChain>;
let chainStub: StubbedChainMutable<"stateCache" | "emitter">;
let stateCacheStub: SinonStubbedInstance<StateContextCache>;
let chainEventEmmitter: ChainEventEmitter;
let api: ReturnType<typeof getEventsApi>;
Expand Down
8 changes: 5 additions & 3 deletions packages/beacon-node/test/unit/api/impl/index.test.ts
Expand Up @@ -7,12 +7,14 @@ import {getBeaconBlockApi} from "../../../../src/api/impl/beacon/blocks/index.js
import {BeaconChain} from "../../../../src/chain/index.js";
import {Network} from "../../../../src/network/index.js";
import {BeaconSync} from "../../../../src/sync/index.js";
import {StubbedBeaconDb} from "../../../utils/stub/index.js";
import {StubbedBeaconDb, StubbedChainMutable} from "../../../utils/stub/index.js";

type StubbedChain = StubbedChainMutable<"forkChoice" | "clock">;

export type ApiImplTestModules = {
sandbox: SinonSandbox;
forkChoiceStub: SinonStubbedInstance<ForkChoice>;
chainStub: SinonStubbedInstance<BeaconChain>;
chainStub: StubbedChain;
syncStub: SinonStubbedInstance<BeaconSync>;
dbStub: StubbedBeaconDb;
networkStub: SinonStubbedInstance<Network>;
Expand All @@ -23,7 +25,7 @@ export type ApiImplTestModules = {
export function setupApiImplTestServer(): ApiImplTestModules {
const sandbox = sinon.createSandbox();
const forkChoiceStub = sinon.createStubInstance(ForkChoice);
const chainStub = sinon.createStubInstance(BeaconChain);
const chainStub = sinon.createStubInstance(BeaconChain) as StubbedChain;
const syncStub = sinon.createStubInstance(BeaconSync);
const dbStub = new StubbedBeaconDb(config);
const networkStub = sinon.createStubInstance(Network);
Expand Down
Expand Up @@ -6,15 +6,14 @@ import {ForkChoice} from "@lodestar/fork-choice";

import {ssz} from "@lodestar/types";
import {MAX_EFFECTIVE_BALANCE, SLOTS_PER_EPOCH} from "@lodestar/params";
import {IBeaconChain} from "../../../../../../src/chain/index.js";
import {LocalClock} from "../../../../../../src/chain/clock/index.js";
import {FAR_FUTURE_EPOCH} from "../../../../../../src/constants/index.js";
import {getValidatorApi} from "../../../../../../src/api/impl/validator/index.js";
import {ApiModules} from "../../../../../../src/api/impl/types.js";
import {generateState} from "../../../../../utils/state.js";
import {IBeaconSync} from "../../../../../../src/sync/index.js";
import {generateValidators} from "../../../../../utils/validator.js";
import {StubbedBeaconDb} from "../../../../../utils/stub/index.js";
import {StubbedBeaconDb, StubbedChainMutable} from "../../../../../utils/stub/index.js";
import {setupApiImplTestServer, ApiImplTestModules} from "../../index.test.js";
import {testLogger} from "../../../../../utils/logger.js";
import {createCachedBeaconStateTest} from "../../../../../utils/cachedBeaconState.js";
Expand All @@ -24,7 +23,7 @@ use(chaiAsPromised);
describe("get proposers api impl", function () {
const logger = testLogger();

let chainStub: SinonStubbedInstance<IBeaconChain>,
let chainStub: StubbedChainMutable<"clock" | "forkChoice">,
syncStub: SinonStubbedInstance<IBeaconSync>,
dbStub: StubbedBeaconDb;

Expand Down
5 changes: 4 additions & 1 deletion packages/beacon-node/test/unit/chain/prepareNextSlot.test.ts
Expand Up @@ -15,6 +15,7 @@ import {BeaconProposerCache} from "../../../src/chain/beaconProposerCache.js";
import {PayloadIdCache} from "../../../src/execution/engine/payloadIdCache.js";
import {ExecutionEngineHttp} from "../../../src/execution/engine/http.js";
import {IExecutionEngine} from "../../../src/execution/engine/interface.js";
import {StubbedChainMutable} from "../../utils/stub/index.js";

describe("PrepareNextSlot scheduler", () => {
const sandbox = sinon.createSandbox();
Expand All @@ -30,7 +31,9 @@ describe("PrepareNextSlot scheduler", () => {

beforeEach(() => {
sandbox.useFakeTimers();
const chainStub = sandbox.createStubInstance(BeaconChain) as SinonStubbedInstance<BeaconChain> & BeaconChain;
const chainStub = sandbox.createStubInstance(BeaconChain) as StubbedChainMutable<
"clock" | "forkChoice" | "emitter" | "regen"
>;
const clockStub = sandbox.createStubInstance(LocalClock) as SinonStubbedInstance<LocalClock> & LocalClock;
chainStub.clock = clockStub;
forkChoiceStub = sandbox.createStubInstance(ForkChoice) as SinonStubbedInstance<ForkChoice> & ForkChoice;
Expand Down
Expand Up @@ -4,14 +4,16 @@ import {ForkChoice} from "@lodestar/fork-choice";
import {phase0, ssz} from "@lodestar/types";

import {BeaconChain} from "../../../../src/chain/index.js";
import {StubbedChain} from "../../../utils/stub/index.js";
import {StubbedChainMutable} from "../../../utils/stub/index.js";
import {generateCachedState} from "../../../utils/state.js";
import {validateGossipAttesterSlashing} from "../../../../src/chain/validation/attesterSlashing.js";
import {AttesterSlashingErrorCode} from "../../../../src/chain/errors/attesterSlashingError.js";
import {OpPool} from "../../../../src/chain/opPools/index.js";
import {expectRejectedWithLodestarError} from "../../../utils/errors.js";
import {BlsVerifierMock} from "../../../utils/mocks/bls.js";

type StubbedChain = StubbedChainMutable<"forkChoice" | "bls">;

describe("GossipMessageValidator", () => {
const sandbox = sinon.createSandbox();
let chainStub: StubbedChain;
Expand Down
7 changes: 5 additions & 2 deletions packages/beacon-node/test/unit/chain/validation/block.test.ts
Expand Up @@ -3,7 +3,7 @@ import {config} from "@lodestar/config/default";
import {ForkChoice, ProtoBlock} from "@lodestar/fork-choice";
import {allForks, ssz} from "@lodestar/types";
import {ForkName} from "@lodestar/params";
import {BeaconChain, IBeaconChain} from "../../../../src/chain/index.js";
import {BeaconChain} from "../../../../src/chain/index.js";
import {LocalClock} from "../../../../src/chain/clock/index.js";
import {StateRegenerator} from "../../../../src/chain/regen/index.js";
import {validateGossipBlock} from "../../../../src/chain/validation/index.js";
Expand All @@ -13,9 +13,12 @@ import {SinonStubFn} from "../../../utils/types.js";
import {expectRejectedWithLodestarError} from "../../../utils/errors.js";
import {SeenBlockProposers} from "../../../../src/chain/seenCache/index.js";
import {EMPTY_SIGNATURE, ZERO_HASH} from "../../../../src/constants/index.js";
import {StubbedChainMutable} from "../../../utils/stub/index.js";

type StubbedChain = StubbedChainMutable<"clock" | "forkChoice" | "regen" | "bls">;

describe("gossip block validation", function () {
let chain: SinonStubbedInstance<IBeaconChain>;
let chain: StubbedChain;
let forkChoice: SinonStubbedInstance<ForkChoice>;
let regen: SinonStubbedInstance<StateRegenerator>;
let verifySignature: SinonStubFn<() => Promise<boolean>>;
Expand Down
Expand Up @@ -4,7 +4,7 @@ import {defaultChainConfig} from "@lodestar/config";
import {BitArray} from "@chainsafe/ssz";
import {SLOTS_PER_EPOCH, SYNC_COMMITTEE_SUBNET_SIZE} from "@lodestar/params";
import {createIChainForkConfig} from "@lodestar/config";
import {BeaconChain, IBeaconChain} from "../../../../src/chain/index.js";
import {BeaconChain} from "../../../../src/chain/index.js";
import {LocalClock} from "../../../../src/chain/clock/index.js";
import {SyncCommitteeErrorCode} from "../../../../src/chain/errors/syncCommitteeError.js";
import {expectRejectedWithLodestarError} from "../../../utils/errors.js";
Expand All @@ -16,12 +16,15 @@ import {SinonStubFn} from "../../../utils/types.js";
import {generateCachedStateWithPubkeys} from "../../../utils/state.js";
import {SeenContributionAndProof} from "../../../../src/chain/seenCache/index.js";
import {BlsVerifierMock} from "../../../utils/mocks/bls.js";
import {StubbedChainMutable} from "../../../utils/stub/index.js";

type StubbedChain = StubbedChainMutable<"clock" | "bls">;

// https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/p2p-interface.md
// TODO remove stub
describe.skip("Sync Committee Contribution And Proof validation", function () {
const sandbox = sinon.createSandbox();
let chain: SinonStubbedInstance<IBeaconChain>;
let chain: StubbedChain;
let clockStub: SinonStubbedInstance<LocalClock>;
let isSyncCommitteeAggregatorStub: SinonStubFn<typeof syncCommitteeUtils["isSyncCommitteeAggregator"]>;

Expand Down
Expand Up @@ -4,14 +4,16 @@ import {ForkChoice} from "@lodestar/fork-choice";
import {phase0, ssz} from "@lodestar/types";

import {BeaconChain} from "../../../../src/chain/index.js";
import {StubbedChain} from "../../../utils/stub/index.js";
import {StubbedChainMutable} from "../../../utils/stub/index.js";
import {generateCachedState} from "../../../utils/state.js";
import {ProposerSlashingErrorCode} from "../../../../src/chain/errors/proposerSlashingError.js";
import {validateGossipProposerSlashing} from "../../../../src/chain/validation/proposerSlashing.js";
import {OpPool} from "../../../../src/chain/opPools/index.js";
import {expectRejectedWithLodestarError} from "../../../utils/errors.js";
import {BlsVerifierMock} from "../../../utils/mocks/bls.js";

type StubbedChain = StubbedChainMutable<"forkChoice" | "bls">;

describe("validate proposer slashing", () => {
const sandbox = sinon.createSandbox();
let chainStub: StubbedChain;
Expand Down
Expand Up @@ -3,7 +3,7 @@ import {SinonStubbedInstance} from "sinon";
import {Epoch} from "@lodestar/types";
import {SLOTS_PER_EPOCH} from "@lodestar/params";
import {createIChainForkConfig, defaultChainConfig} from "@lodestar/config";
import {BeaconChain, IBeaconChain} from "../../../../src/chain/index.js";
import {BeaconChain} from "../../../../src/chain/index.js";
import {LocalClock} from "../../../../src/chain/clock/index.js";
import {SyncCommitteeErrorCode} from "../../../../src/chain/errors/syncCommitteeError.js";
import {validateGossipSyncCommittee} from "../../../../src/chain/validation/syncCommittee.js";
Expand All @@ -12,11 +12,14 @@ import {generateCachedState} from "../../../utils/state.js";
import {generateSyncCommitteeSignature} from "../../../utils/syncCommittee.js";
import {SeenSyncCommitteeMessages} from "../../../../src/chain/seenCache/index.js";
import {BlsVerifierMock} from "../../../utils/mocks/bls.js";
import {StubbedChainMutable} from "../../../utils/stub/index.js";

type StubbedChain = StubbedChainMutable<"clock" | "bls">;

// https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/p2p-interface.md
describe("Sync Committee Signature validation", function () {
const sandbox = sinon.createSandbox();
let chain: SinonStubbedInstance<IBeaconChain>;
let chain: StubbedChain;
let clockStub: SinonStubbedInstance<LocalClock>;
// let computeSubnetsForSyncCommitteeStub: SinonStubFn<typeof syncCommitteeUtils["computeSubnetsForSyncCommittee"]>;
let altairForkEpochBk: Epoch;
Expand Down
Expand Up @@ -15,7 +15,7 @@ import bls from "@chainsafe/bls";
import {PointFormat} from "@chainsafe/bls/types";
import {createIBeaconConfig} from "@lodestar/config";
import {BeaconChain} from "../../../../src/chain/index.js";
import {StubbedChain} from "../../../utils/stub/index.js";
import {StubbedChainMutable} from "../../../utils/stub/index.js";
import {generateState} from "../../../utils/state.js";
import {validateGossipVoluntaryExit} from "../../../../src/chain/validation/voluntaryExit.js";
import {VoluntaryExitErrorCode} from "../../../../src/chain/errors/voluntaryExitError.js";
Expand All @@ -24,6 +24,8 @@ import {expectRejectedWithLodestarError} from "../../../utils/errors.js";
import {createCachedBeaconStateTest} from "../../../utils/cachedBeaconState.js";
import {BlsVerifierMock} from "../../../utils/mocks/bls.js";

type StubbedChain = StubbedChainMutable<"forkChoice" | "bls">;

describe("validate voluntary exit", () => {
const sandbox = sinon.createSandbox();
let chainStub: StubbedChain;
Expand Down
5 changes: 5 additions & 0 deletions packages/beacon-node/test/utils/stub/index.ts
@@ -1,6 +1,11 @@
import {SinonStubbedInstance} from "sinon";
import {IBeaconChain} from "../../../src/chain/index.js";
import {Mutable} from "../types.js";

export type StubbedChain = IBeaconChain & SinonStubbedInstance<IBeaconChain>;
export type StubbedOf<T> = T & SinonStubbedInstance<T>;

/** Helper type to make dependencies mutable for validation tests */
export type StubbedChainMutable<K extends keyof IBeaconChain> = StubbedOf<Mutable<IBeaconChain, K>>;

export * from "./beaconDb.js";
2 changes: 2 additions & 0 deletions packages/beacon-node/test/utils/types.ts
Expand Up @@ -11,3 +11,5 @@ type StubbableType<TType> = Function & {prototype: TType};
export function createStubInstance<TType>(constructor: StubbableType<TType>): SinonStubbedInstance<TType> & TType {
return sinon.createStubInstance(constructor) as SinonStubbedInstance<TType> & TType;
}

export type Mutable<T, K extends keyof T> = Omit<T, K> & {-readonly [key in K]: T[key]};

0 comments on commit ac5398e

Please sign in to comment.