Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Remove sinon in favor of a date provider #10705

Merged
merged 2 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ import { type ContractArtifact } from '@aztec/foundation/abi';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { padArrayEnd } from '@aztec/foundation/collection';
import { type Logger, createLogger } from '@aztec/foundation/log';
import { Timer } from '@aztec/foundation/timer';
import { DateProvider, Timer } from '@aztec/foundation/timer';
import { type AztecKVStore } from '@aztec/kv-store';
import { openTmpStore } from '@aztec/kv-store/lmdb';
import { SHA256Trunc, StandardTree, UnbalancedTree } from '@aztec/merkle-tree';
Expand Down Expand Up @@ -136,10 +136,12 @@ export class AztecNodeService implements AztecNode {
telemetry?: TelemetryClient;
logger?: Logger;
publisher?: L1Publisher;
dateProvider?: DateProvider;
} = {},
): Promise<AztecNodeService> {
const telemetry = deps.telemetry ?? new NoopTelemetryClient();
const log = deps.logger ?? createLogger('node');
const dateProvider = deps.dateProvider ?? new DateProvider();
const ethereumChain = createEthereumChain(config.l1RpcUrl, config.l1ChainId);
//validate that the actual chain id matches that specified in configuration
if (config.l1ChainId !== ethereumChain.chainInfo.id) {
Expand All @@ -152,7 +154,8 @@ export class AztecNodeService implements AztecNode {

// we identify the P2P transaction protocol by using the rollup contract address.
// this may well change in future
config.transactionProtocol = `/aztec/tx/${config.l1Contracts.rollupAddress.toString()}`;
const rollupAddress = config.l1Contracts.rollupAddress;
config.transactionProtocol = `/aztec/tx/${rollupAddress.toString()}`;

// now create the merkle trees and the world state synchronizer
const worldStateSynchronizer = await createWorldStateSynchronizer(config, archiver, telemetry);
Expand All @@ -167,7 +170,7 @@ export class AztecNodeService implements AztecNode {
// start both and wait for them to sync from the block source
await Promise.all([p2pClient.start(), worldStateSynchronizer.start()]);

const validatorClient = await createValidatorClient(config, config.l1Contracts.rollupAddress, p2pClient, telemetry);
const validatorClient = await createValidatorClient(config, rollupAddress, { p2pClient, telemetry, dateProvider });

// now create the sequencer
const sequencer = config.disableValidator
Expand Down
1 change: 0 additions & 1 deletion yarn-project/end-to-end/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@
"devDependencies": {
"0x": "^5.7.0",
"@jest/globals": "^29.5.0",
"@sinonjs/fake-timers": "^13.0.5",
"@types/jest": "^29.5.0",
"@types/js-yaml": "^4.0.9",
"@types/lodash.chunk": "^4.2.9",
Expand Down
1 change: 1 addition & 0 deletions yarn-project/end-to-end/src/e2e_p2p/gossip_network.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ describe('e2e_p2p_network', () => {
t.logger.info('Creating nodes');
nodes = await createNodes(
t.ctx.aztecNodeConfig,
t.ctx.dateProvider,
t.bootstrapNodeEnr,
NUM_NODES,
BOOT_NODE_UDP_PORT,
Expand Down
13 changes: 6 additions & 7 deletions yarn-project/end-to-end/src/e2e_p2p/p2p_network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export class P2PNetworkTest {
*/
public async syncMockSystemTime() {
this.logger.info('Syncing mock system time');
const { timer, deployL1ContractsValues } = this.ctx!;
const { dateProvider, deployL1ContractsValues } = this.ctx!;
// Send a tx and only update the time after the tx is mined, as eth time is not continuous
const tx = await deployL1ContractsValues.walletClient.sendTransaction({
to: this.baseAccount.address,
Expand All @@ -104,8 +104,7 @@ export class P2PNetworkTest {
hash: tx,
});
const timestamp = await deployL1ContractsValues.publicClient.getBlock({ blockNumber: receipt.blockNumber });
timer.setSystemTime(Number(timestamp.timestamp) * 1000);
this.logger.info(`Synced mock system time to ${timestamp.timestamp * 1000n}`);
dateProvider.setTime(Number(timestamp.timestamp) * 1000);
}

static async create({
Expand Down Expand Up @@ -133,7 +132,7 @@ export class P2PNetworkTest {
async applyBaseSnapshots() {
await this.snapshotManager.snapshot(
'add-validators',
async ({ deployL1ContractsValues, aztecNodeConfig, timer }) => {
async ({ deployL1ContractsValues, aztecNodeConfig, dateProvider }) => {
const rollup = getContract({
address: deployL1ContractsValues.l1ContractAddresses.rollupAddress.toString(),
abi: RollupAbi,
Expand Down Expand Up @@ -203,7 +202,7 @@ export class P2PNetworkTest {

// Set the system time in the node, only after we have warped the time and waited for a block
// Time is only set in the NEXT block
timer.setSystemTime(Number(timestamp) * 1000);
dateProvider.setTime(Number(timestamp) * 1000);
},
);
}
Expand Down Expand Up @@ -244,7 +243,7 @@ export class P2PNetworkTest {
async removeInitialNode() {
await this.snapshotManager.snapshot(
'remove-inital-validator',
async ({ deployL1ContractsValues, aztecNode, timer }) => {
async ({ deployL1ContractsValues, aztecNode, dateProvider }) => {
// Send and await a tx to make sure we mine a block for the warp to correctly progress.
const receipt = await deployL1ContractsValues.publicClient.waitForTransactionReceipt({
hash: await deployL1ContractsValues.walletClient.sendTransaction({
Expand All @@ -256,7 +255,7 @@ export class P2PNetworkTest {
const block = await deployL1ContractsValues.publicClient.getBlock({
blockNumber: receipt.blockNumber,
});
timer.setSystemTime(Number(block.timestamp) * 1000);
dateProvider.setTime(Number(block.timestamp) * 1000);

await aztecNode.stop();
},
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/end-to-end/src/e2e_p2p/rediscovery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ describe('e2e_p2p_rediscovery', () => {
const contexts: NodeContext[] = [];
nodes = await createNodes(
t.ctx.aztecNodeConfig,
t.ctx.dateProvider,
t.bootstrapNodeEnr,
NUM_NODES,
BOOT_NODE_UDP_PORT,
Expand All @@ -72,6 +73,7 @@ describe('e2e_p2p_rediscovery', () => {

const newNode = await createNode(
t.ctx.aztecNodeConfig,
t.ctx.dateProvider,
i + 1 + BOOT_NODE_UDP_PORT,
undefined,
i,
Expand Down
1 change: 1 addition & 0 deletions yarn-project/end-to-end/src/e2e_p2p/reex.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ describe('e2e_p2p_reex', () => {

nodes = await createNodes(
t.ctx.aztecNodeConfig,
t.ctx.dateProvider,
t.bootstrapNodeEnr,
NUM_NODES,
BOOT_NODE_UDP_PORT,
Expand Down
1 change: 1 addition & 0 deletions yarn-project/end-to-end/src/e2e_p2p/reqresp.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ describe('e2e_p2p_reqresp_tx', () => {
t.logger.info('Creating nodes');
nodes = await createNodes(
t.ctx.aztecNodeConfig,
t.ctx.dateProvider,
t.bootstrapNodeEnr,
NUM_NODES,
BOOT_NODE_UDP_PORT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ describe('e2e_p2p_governance_proposer', () => {
t.logger.info('Creating nodes');
nodes = await createNodes(
{ ...t.ctx.aztecNodeConfig, governanceProposerPayload: newPayloadAddress },
t.ctx.dateProvider,
t.bootstrapNodeEnr,
NUM_NODES,
BOOT_NODE_UDP_PORT,
Expand Down
6 changes: 5 additions & 1 deletion yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { type AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
import { type SentTx, createLogger } from '@aztec/aztec.js';
import { type AztecAddress } from '@aztec/circuits.js';
import { type DateProvider } from '@aztec/foundation/timer';
import { type PXEService } from '@aztec/pxe';

import getPort from 'get-port';
Expand Down Expand Up @@ -34,6 +35,7 @@ export function generatePrivateKeys(startIndex: number, numberOfKeys: number): `

export function createNodes(
config: AztecNodeConfig,
dateProvider: DateProvider,
bootstrapNodeEnr: string,
numNodes: number,
bootNodePort: number,
Expand All @@ -46,7 +48,7 @@ export function createNodes(
const port = bootNodePort + i + 1;

const dataDir = dataDirectory ? `${dataDirectory}-${i}` : undefined;
const nodePromise = createNode(config, port, bootstrapNodeEnr, i, dataDir, metricsPort);
const nodePromise = createNode(config, dateProvider, port, bootstrapNodeEnr, i, dataDir, metricsPort);
nodePromises.push(nodePromise);
}
return Promise.all(nodePromises);
Expand All @@ -55,6 +57,7 @@ export function createNodes(
// creates a P2P enabled instance of Aztec Node Service
export async function createNode(
config: AztecNodeConfig,
dateProvider: DateProvider,
tcpPort: number,
bootstrapNode: string | undefined,
accountIndex: number,
Expand All @@ -68,6 +71,7 @@ export async function createNode(
return await AztecNodeService.createAndSync(validatorConfig, {
telemetry: telemetryClient,
logger: createLogger(`node:${tcpPort}`),
dateProvider,
});
}

Expand Down
21 changes: 8 additions & 13 deletions yarn-project/end-to-end/src/fixtures/snapshot_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ import { startAnvil } from '@aztec/ethereum/test';
import { asyncMap } from '@aztec/foundation/async-map';
import { createLogger } from '@aztec/foundation/log';
import { resolver, reviver } from '@aztec/foundation/serialize';
import { TestDateProvider } from '@aztec/foundation/timer';
import { type ProverNode } from '@aztec/prover-node';
import { type PXEService, createPXEService, getPXEServiceConfig } from '@aztec/pxe';
import { createAndStartTelemetryClient, getConfigEnvVars as getTelemetryConfig } from '@aztec/telemetry-client/start';

import { type InstalledClock, install } from '@sinonjs/fake-timers';
import { type Anvil } from '@viem/anvil';
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
import { copySync, removeSync } from 'fs-extra/esm';
Expand All @@ -50,7 +50,7 @@ export type SubsystemsContext = {
proverNode?: ProverNode;
watcher: AnvilTestWatcher;
cheatCodes: CheatCodes;
timer: InstalledClock;
dateProvider: TestDateProvider;
};

type SnapshotEntry = {
Expand Down Expand Up @@ -250,7 +250,6 @@ async function teardown(context: SubsystemsContext | undefined) {
await context.acvmConfig?.cleanup();
await context.anvil.stop();
await context.watcher.stop();
context.timer?.uninstall();
} catch (err) {
getLogger().error('Error during teardown', err);
}
Expand All @@ -272,9 +271,6 @@ async function setupFromFresh(
): Promise<SubsystemsContext> {
logger.verbose(`Initializing state...`);

// Use sinonjs fake timers
const timer = install({ shouldAdvanceTime: true, advanceTimeDelta: 20, toFake: ['Date'] });

// Fetch the AztecNode config.
// TODO: For some reason this is currently the union of a bunch of subsystems. That needs fixing.
const aztecNodeConfig: AztecNodeConfig & SetupOptions = { ...getConfigEnvVars(), ...opts };
Expand Down Expand Up @@ -358,7 +354,8 @@ async function setupFromFresh(
const telemetry = await getEndToEndTestTelemetryClient(opts.metricsPort);

logger.verbose('Creating and synching an aztec node...');
const aztecNode = await AztecNodeService.createAndSync(aztecNodeConfig, { telemetry });
const dateProvider = new TestDateProvider();
const aztecNode = await AztecNodeService.createAndSync(aztecNodeConfig, { telemetry, dateProvider });

let proverNode: ProverNode | undefined = undefined;
if (opts.startProverNode) {
Expand Down Expand Up @@ -392,7 +389,7 @@ async function setupFromFresh(
proverNode,
watcher,
cheatCodes,
timer,
dateProvider,
};
}

Expand All @@ -402,9 +399,6 @@ async function setupFromFresh(
async function setupFromState(statePath: string, logger: Logger): Promise<SubsystemsContext> {
logger.verbose(`Initializing with saved state at ${statePath}...`);

// TODO: make one function
const timer = install({ shouldAdvanceTime: true, advanceTimeDelta: 20, toFake: ['Date'] });

// TODO: For some reason this is currently the union of a bunch of subsystems. That needs fixing.
const aztecNodeConfig: AztecNodeConfig & SetupOptions = JSON.parse(
readFileSync(`${statePath}/aztec_node_config.json`, 'utf-8'),
Expand Down Expand Up @@ -445,7 +439,8 @@ async function setupFromState(statePath: string, logger: Logger): Promise<Subsys

logger.verbose('Creating aztec node...');
const telemetry = await createAndStartTelemetryClient(getTelemetryConfig());
const aztecNode = await AztecNodeService.createAndSync(aztecNodeConfig, { telemetry });
const dateProvider = new TestDateProvider();
const aztecNode = await AztecNodeService.createAndSync(aztecNodeConfig, { telemetry, dateProvider });

let proverNode: ProverNode | undefined = undefined;
if (aztecNodeConfig.startProverNode) {
Expand Down Expand Up @@ -477,7 +472,7 @@ async function setupFromState(statePath: string, logger: Logger): Promise<Subsys
},
watcher,
cheatCodes,
timer,
dateProvider,
};
}

Expand Down
8 changes: 7 additions & 1 deletion yarn-project/end-to-end/src/fixtures/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
} from '@aztec/ethereum';
import { startAnvil } from '@aztec/ethereum/test';
import { retryUntil } from '@aztec/foundation/retry';
import { TestDateProvider } from '@aztec/foundation/timer';
import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice';
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types';
import { ProtocolContractAddress, protocolContractTreeRoot } from '@aztec/protocol-contracts';
Expand Down Expand Up @@ -225,6 +226,7 @@ async function setupWithRemoteEnvironment(
logger,
cheatCodes,
watcher: undefined,
dateProvider: undefined,
teardown,
};
}
Expand Down Expand Up @@ -279,6 +281,8 @@ export type EndToEndContext = {
cheatCodes: CheatCodes;
/** The anvil test watcher (undefined if connected to remove environment) */
watcher: AnvilTestWatcher | undefined;
/** Allows tweaking current system time, used by the epoch cache only (undefined if connected to remove environment) */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** Allows tweaking current system time, used by the epoch cache only (undefined if connected to remove environment) */
/** Allows tweaking current system time, used by the epoch cache only (undefined if connected to remote environment) */

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Serves me well for copypasting from the line above

dateProvider: TestDateProvider | undefined;
/** Function to stop the started services. */
teardown: () => Promise<void>;
};
Expand Down Expand Up @@ -415,7 +419,8 @@ export async function setup(

const telemetry = await telemetryPromise;
const publisher = new TestL1Publisher(config, telemetry);
const aztecNode = await AztecNodeService.createAndSync(config, { telemetry, publisher });
const dateProvider = new TestDateProvider();
const aztecNode = await AztecNodeService.createAndSync(config, { telemetry, publisher, dateProvider });
const sequencer = aztecNode.getSequencer();

let proverNode: ProverNode | undefined = undefined;
Expand Down Expand Up @@ -466,6 +471,7 @@ export async function setup(
cheatCodes,
sequencer,
watcher,
dateProvider,
teardown,
};
}
Expand Down
20 changes: 15 additions & 5 deletions yarn-project/epoch-cache/src/epoch_cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
import { RollupContract, createEthereumChain } from '@aztec/ethereum';
import { EthAddress } from '@aztec/foundation/eth-address';
import { type Logger, createLogger } from '@aztec/foundation/log';
import { DateProvider } from '@aztec/foundation/timer';

import { EventEmitter } from 'node:events';
import { createPublicClient, encodeAbiParameters, http, keccak256 } from 'viem';
Expand Down Expand Up @@ -40,17 +41,22 @@ export class EpochCache extends EventEmitter<{ committeeChanged: [EthAddress[],
initialValidators: EthAddress[] = [],
initialSampleSeed: bigint = 0n,
private readonly l1constants: L1RollupConstants = EmptyL1RollupConstants,
private readonly dateProvider: DateProvider = new DateProvider(),
) {
super();
this.committee = initialValidators;
this.cachedSampleSeed = initialSampleSeed;

this.log.debug(`Initialized EpochCache with constants and validators`, { l1constants, initialValidators });

this.cachedEpoch = getEpochNumberAtTimestamp(BigInt(Math.floor(Date.now() / 1000)), this.l1constants);
this.cachedEpoch = getEpochNumberAtTimestamp(this.nowInSeconds(), this.l1constants);
}

static async create(rollupAddress: EthAddress, config?: EpochCacheConfig) {
static async create(
rollupAddress: EthAddress,
config?: EpochCacheConfig,
deps: { dateProvider?: DateProvider } = {},
) {
config = config ?? getEpochCacheConfigEnvVars();

const chain = createEthereumChain(config.l1RpcUrl, config.l1ChainId);
Expand Down Expand Up @@ -81,16 +87,20 @@ export class EpochCache extends EventEmitter<{ committeeChanged: [EthAddress[],
initialValidators.map(v => EthAddress.fromString(v)),
sampleSeed,
l1RollupConstants,
deps.dateProvider,
);
}

private nowInSeconds(): bigint {
return BigInt(Math.floor(this.dateProvider.now() / 1000));
}

getEpochAndSlotNow(): EpochAndSlot {
const now = BigInt(Math.floor(Date.now() / 1000));
return this.getEpochAndSlotAtTimestamp(now);
return this.getEpochAndSlotAtTimestamp(this.nowInSeconds());
}

getEpochAndSlotInNextSlot(): EpochAndSlot {
const nextSlotTs = BigInt(Math.floor(Date.now() / 1000) + this.l1constants.slotDuration);
const nextSlotTs = this.nowInSeconds() + BigInt(this.l1constants.slotDuration);
return this.getEpochAndSlotAtTimestamp(nextSlotTs);
}

Expand Down
Loading
Loading