@aztec/epoch-cache 0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2 → 0.77.0-testnet-ignition.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ import { type L1ContractsConfig, type L1ReaderConfig } from '@aztec/ethereum';
2
+ export type EpochCacheConfig = Pick<L1ReaderConfig & L1ContractsConfig, 'l1RpcUrls' | 'l1ChainId' | 'viemPollingIntervalMS' | 'aztecSlotDuration' | 'ethereumSlotDuration' | 'aztecEpochDuration'>;
3
+ export declare function getEpochCacheConfigEnvVars(): EpochCacheConfig;
4
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAGpB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,cAAc,GAAG,iBAAiB,EAChC,WAAW,GACX,WAAW,GACX,uBAAuB,GACvB,mBAAmB,GACnB,sBAAsB,GACtB,oBAAoB,CACvB,CAAC;AAEF,wBAAgB,0BAA0B,IAAI,gBAAgB,CAE7D"}
@@ -0,0 +1,87 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ import { RollupContract } from '@aztec/ethereum';
3
+ import { EthAddress } from '@aztec/foundation/eth-address';
4
+ import { DateProvider } from '@aztec/foundation/timer';
5
+ import { type L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
6
+ import { EventEmitter } from 'node:events';
7
+ import { type EpochCacheConfig } from './config.js';
8
+ type EpochAndSlot = {
9
+ epoch: bigint;
10
+ slot: bigint;
11
+ ts: bigint;
12
+ };
13
+ export interface EpochCacheInterface {
14
+ getCommittee(nextSlot: boolean): Promise<EthAddress[]>;
15
+ getEpochAndSlotNow(): EpochAndSlot;
16
+ getProposerIndexEncoding(epoch: bigint, slot: bigint, seed: bigint): `0x${string}`;
17
+ computeProposerIndex(slot: bigint, epoch: bigint, seed: bigint, size: bigint): bigint;
18
+ getProposerInCurrentOrNextSlot(): Promise<{
19
+ currentProposer: EthAddress;
20
+ nextProposer: EthAddress;
21
+ currentSlot: bigint;
22
+ nextSlot: bigint;
23
+ }>;
24
+ isInCommittee(validator: EthAddress): Promise<boolean>;
25
+ }
26
+ /**
27
+ * Epoch cache
28
+ *
29
+ * This class is responsible for managing traffic to the l1 node, by caching the validator set.
30
+ * It also provides a method to get the current or next proposer, and to check who is in the current slot.
31
+ *
32
+ * If the epoch changes, then we update the stored validator set.
33
+ *
34
+ * Note: This class is very dependent on the system clock being in sync.
35
+ */
36
+ export declare class EpochCache extends EventEmitter<{
37
+ committeeChanged: [EthAddress[], bigint];
38
+ }> implements EpochCacheInterface {
39
+ private rollup;
40
+ private readonly l1constants;
41
+ private readonly dateProvider;
42
+ private committee;
43
+ private cachedEpoch;
44
+ private cachedSampleSeed;
45
+ private readonly log;
46
+ constructor(rollup: RollupContract, initialValidators?: EthAddress[], initialSampleSeed?: bigint, l1constants?: L1RollupConstants, dateProvider?: DateProvider);
47
+ static create(rollupAddress: EthAddress, config?: EpochCacheConfig, deps?: {
48
+ dateProvider?: DateProvider;
49
+ }): Promise<EpochCache>;
50
+ private nowInSeconds;
51
+ getEpochAndSlotNow(): EpochAndSlot;
52
+ private getEpochAndSlotInNextSlot;
53
+ private getEpochAndSlotAtTimestamp;
54
+ /**
55
+ * Get the current validator set
56
+ *
57
+ * @param nextSlot - If true, get the validator set for the next slot.
58
+ * @returns The current validator set.
59
+ */
60
+ getCommittee(nextSlot?: boolean): Promise<EthAddress[]>;
61
+ /**
62
+ * Get the ABI encoding of the proposer index - see ValidatorSelectionLib.sol computeProposerIndex
63
+ */
64
+ getProposerIndexEncoding(epoch: bigint, slot: bigint, seed: bigint): `0x${string}`;
65
+ computeProposerIndex(slot: bigint, epoch: bigint, seed: bigint, size: bigint): bigint;
66
+ /**
67
+ * Returns the current and next proposer
68
+ *
69
+ * We return the next proposer as the node will check if it is the proposer at the next ethereum block, which
70
+ * can be the next slot. If this is the case, then it will send proposals early.
71
+ *
72
+ * If we are at an epoch boundary, then we can update the cache for the next epoch, this is the last check
73
+ * we do in the validator client, so we can update the cache here.
74
+ */
75
+ getProposerInCurrentOrNextSlot(): Promise<{
76
+ currentProposer: EthAddress;
77
+ nextProposer: EthAddress;
78
+ currentSlot: bigint;
79
+ nextSlot: bigint;
80
+ }>;
81
+ /**
82
+ * Check if a validator is in the current epoch's committee
83
+ */
84
+ isInCommittee(validator: EthAddress): Promise<boolean>;
85
+ }
86
+ export {};
87
+ //# sourceMappingURL=epoch_cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epoch_cache.d.ts","sourceRoot":"","sources":["../src/epoch_cache.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,10 @@
1
- import { EmptyL1RollupConstants, getEpochNumberAtTimestamp, getSlotAtTimestamp } from '@aztec/circuit-types';
2
1
  import { RollupContract, createEthereumChain } from '@aztec/ethereum';
3
2
  import { EthAddress } from '@aztec/foundation/eth-address';
4
3
  import { createLogger } from '@aztec/foundation/log';
5
4
  import { DateProvider } from '@aztec/foundation/timer';
5
+ import { EmptyL1RollupConstants, getEpochNumberAtTimestamp, getSlotAtTimestamp } from '@aztec/stdlib/epoch-helpers';
6
6
  import { EventEmitter } from 'node:events';
7
- import { createPublicClient, encodeAbiParameters, http, keccak256 } from 'viem';
7
+ import { createPublicClient, encodeAbiParameters, fallback, http, keccak256 } from 'viem';
8
8
  import { getEpochCacheConfigEnvVars } from './config.js';
9
9
  /**
10
10
  * Epoch cache
@@ -35,10 +35,10 @@ import { getEpochCacheConfigEnvVars } from './config.js';
35
35
  }
36
36
  static async create(rollupAddress, config, deps = {}) {
37
37
  config = config ?? getEpochCacheConfigEnvVars();
38
- const chain = createEthereumChain(config.l1RpcUrl, config.l1ChainId);
38
+ const chain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
39
39
  const publicClient = createPublicClient({
40
40
  chain: chain.chainInfo,
41
- transport: http(chain.rpcUrl),
41
+ transport: fallback(config.l1RpcUrls.map((url)=>http(url))),
42
42
  pollingInterval: config.viemPollingIntervalMS
43
43
  });
44
44
  const rollup = new RollupContract(publicClient, rollupAddress.toString());
@@ -0,0 +1,3 @@
1
+ export * from './epoch_cache.js';
2
+ export * from './config.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=timestamp_provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timestamp_provider.d.ts","sourceRoot":"","sources":["../src/timestamp_provider.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/epoch-cache",
3
- "version": "0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2",
3
+ "version": "0.77.0-testnet-ignition.17",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -28,10 +28,10 @@
28
28
  "../package.common.json"
29
29
  ],
30
30
  "dependencies": {
31
- "@aztec/circuit-types": "0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2",
32
- "@aztec/ethereum": "0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2",
33
- "@aztec/foundation": "0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2",
34
- "@aztec/l1-artifacts": "0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2",
31
+ "@aztec/ethereum": "0.77.0-testnet-ignition.17",
32
+ "@aztec/foundation": "0.77.0-testnet-ignition.17",
33
+ "@aztec/l1-artifacts": "0.77.0-testnet-ignition.17",
34
+ "@aztec/stdlib": "0.77.0-testnet-ignition.17",
35
35
  "@viem/anvil": "^0.0.10",
36
36
  "dotenv": "^16.0.3",
37
37
  "get-port": "^7.1.0",
@@ -82,7 +82,7 @@
82
82
  "reporters": [
83
83
  "default"
84
84
  ],
85
- "testTimeout": 30000,
85
+ "testTimeout": 120000,
86
86
  "setupFiles": [
87
87
  "../../foundation/src/jest/setup.mjs"
88
88
  ]
package/src/config.ts CHANGED
@@ -7,7 +7,7 @@ import {
7
7
 
8
8
  export type EpochCacheConfig = Pick<
9
9
  L1ReaderConfig & L1ContractsConfig,
10
- | 'l1RpcUrl'
10
+ | 'l1RpcUrls'
11
11
  | 'l1ChainId'
12
12
  | 'viemPollingIntervalMS'
13
13
  | 'aztecSlotDuration'
@@ -1,16 +1,16 @@
1
+ import { RollupContract, createEthereumChain } from '@aztec/ethereum';
2
+ import { EthAddress } from '@aztec/foundation/eth-address';
3
+ import { type Logger, createLogger } from '@aztec/foundation/log';
4
+ import { DateProvider } from '@aztec/foundation/timer';
1
5
  import {
2
6
  EmptyL1RollupConstants,
3
7
  type L1RollupConstants,
4
8
  getEpochNumberAtTimestamp,
5
9
  getSlotAtTimestamp,
6
- } from '@aztec/circuit-types';
7
- import { RollupContract, createEthereumChain } from '@aztec/ethereum';
8
- import { EthAddress } from '@aztec/foundation/eth-address';
9
- import { type Logger, createLogger } from '@aztec/foundation/log';
10
- import { DateProvider } from '@aztec/foundation/timer';
10
+ } from '@aztec/stdlib/epoch-helpers';
11
11
 
12
12
  import { EventEmitter } from 'node:events';
13
- import { createPublicClient, encodeAbiParameters, http, keccak256 } from 'viem';
13
+ import { createPublicClient, encodeAbiParameters, fallback, http, keccak256 } from 'viem';
14
14
 
15
15
  import { type EpochCacheConfig, getEpochCacheConfigEnvVars } from './config.js';
16
16
 
@@ -20,6 +20,20 @@ type EpochAndSlot = {
20
20
  ts: bigint;
21
21
  };
22
22
 
23
+ export interface EpochCacheInterface {
24
+ getCommittee(nextSlot: boolean): Promise<EthAddress[]>;
25
+ getEpochAndSlotNow(): EpochAndSlot;
26
+ getProposerIndexEncoding(epoch: bigint, slot: bigint, seed: bigint): `0x${string}`;
27
+ computeProposerIndex(slot: bigint, epoch: bigint, seed: bigint, size: bigint): bigint;
28
+ getProposerInCurrentOrNextSlot(): Promise<{
29
+ currentProposer: EthAddress;
30
+ nextProposer: EthAddress;
31
+ currentSlot: bigint;
32
+ nextSlot: bigint;
33
+ }>;
34
+ isInCommittee(validator: EthAddress): Promise<boolean>;
35
+ }
36
+
23
37
  /**
24
38
  * Epoch cache
25
39
  *
@@ -30,7 +44,10 @@ type EpochAndSlot = {
30
44
  *
31
45
  * Note: This class is very dependent on the system clock being in sync.
32
46
  */
33
- export class EpochCache extends EventEmitter<{ committeeChanged: [EthAddress[], bigint] }> {
47
+ export class EpochCache
48
+ extends EventEmitter<{ committeeChanged: [EthAddress[], bigint] }>
49
+ implements EpochCacheInterface
50
+ {
34
51
  private committee: EthAddress[];
35
52
  private cachedEpoch: bigint;
36
53
  private cachedSampleSeed: bigint;
@@ -59,10 +76,10 @@ export class EpochCache extends EventEmitter<{ committeeChanged: [EthAddress[],
59
76
  ) {
60
77
  config = config ?? getEpochCacheConfigEnvVars();
61
78
 
62
- const chain = createEthereumChain(config.l1RpcUrl, config.l1ChainId);
79
+ const chain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
63
80
  const publicClient = createPublicClient({
64
81
  chain: chain.chainInfo,
65
- transport: http(chain.rpcUrl),
82
+ transport: fallback(config.l1RpcUrls.map(url => http(url))),
66
83
  pollingInterval: config.viemPollingIntervalMS,
67
84
  });
68
85
 
@@ -99,12 +116,12 @@ export class EpochCache extends EventEmitter<{ committeeChanged: [EthAddress[],
99
116
  return this.getEpochAndSlotAtTimestamp(this.nowInSeconds());
100
117
  }
101
118
 
102
- getEpochAndSlotInNextSlot(): EpochAndSlot {
119
+ private getEpochAndSlotInNextSlot(): EpochAndSlot {
103
120
  const nextSlotTs = this.nowInSeconds() + BigInt(this.l1constants.slotDuration);
104
121
  return this.getEpochAndSlotAtTimestamp(nextSlotTs);
105
122
  }
106
123
 
107
- getEpochAndSlotAtTimestamp(ts: bigint): EpochAndSlot {
124
+ private getEpochAndSlotAtTimestamp(ts: bigint): EpochAndSlot {
108
125
  return {
109
126
  epoch: getEpochNumberAtTimestamp(ts, this.l1constants),
110
127
  slot: getSlotAtTimestamp(ts, this.l1constants),