@aztec/epoch-cache 1.2.1 → 2.0.0-nightly.20250814
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.
- package/dest/epoch_cache.d.ts +15 -8
- package/dest/epoch_cache.d.ts.map +1 -1
- package/dest/epoch_cache.js +27 -7
- package/package.json +5 -5
- package/src/epoch_cache.ts +43 -13
package/dest/epoch_cache.d.ts
CHANGED
|
@@ -13,8 +13,9 @@ export type EpochCommitteeInfo = {
|
|
|
13
13
|
seed: bigint;
|
|
14
14
|
epoch: bigint;
|
|
15
15
|
};
|
|
16
|
+
export type SlotTag = 'now' | 'next' | bigint;
|
|
16
17
|
export interface EpochCacheInterface {
|
|
17
|
-
getCommittee(slot:
|
|
18
|
+
getCommittee(slot: SlotTag | undefined): Promise<EpochCommitteeInfo>;
|
|
18
19
|
getEpochAndSlotNow(): EpochAndSlot;
|
|
19
20
|
getEpochAndSlotInNextL1Slot(): EpochAndSlot & {
|
|
20
21
|
now: bigint;
|
|
@@ -27,7 +28,9 @@ export interface EpochCacheInterface {
|
|
|
27
28
|
currentSlot: bigint;
|
|
28
29
|
nextSlot: bigint;
|
|
29
30
|
}>;
|
|
30
|
-
|
|
31
|
+
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
32
|
+
isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
|
|
33
|
+
filterInCommittee(slot: SlotTag, validators: EthAddress[]): Promise<EthAddress[]>;
|
|
31
34
|
}
|
|
32
35
|
/**
|
|
33
36
|
* Epoch cache
|
|
@@ -44,9 +47,12 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
44
47
|
private readonly dateProvider;
|
|
45
48
|
private readonly config;
|
|
46
49
|
private cache;
|
|
50
|
+
private allValidators;
|
|
51
|
+
private lastValidatorRefresh;
|
|
47
52
|
private readonly log;
|
|
48
53
|
constructor(rollup: RollupContract, initialEpoch?: bigint, initialValidators?: EthAddress[] | undefined, initialSampleSeed?: bigint, l1constants?: L1RollupConstants, dateProvider?: DateProvider, config?: {
|
|
49
54
|
cacheSize: number;
|
|
55
|
+
validatorRefreshIntervalSeconds: number;
|
|
50
56
|
});
|
|
51
57
|
static create(rollupAddress: EthAddress, config?: EpochCacheConfig, deps?: {
|
|
52
58
|
dateProvider?: DateProvider;
|
|
@@ -67,7 +73,7 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
67
73
|
* @param nextSlot - If true, get the validator set for the next slot.
|
|
68
74
|
* @returns The current validator set.
|
|
69
75
|
*/
|
|
70
|
-
getCommittee(slot?:
|
|
76
|
+
getCommittee(slot?: SlotTag): Promise<EpochCommitteeInfo>;
|
|
71
77
|
private getEpochAndTimestamp;
|
|
72
78
|
private computeCommittee;
|
|
73
79
|
/**
|
|
@@ -100,10 +106,11 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
100
106
|
* If the committee is empty (i.e. target committee size is 0, and anyone can propose), we return undefined.
|
|
101
107
|
*/
|
|
102
108
|
private getProposerAttesterAddressAt;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
filterInCommittee(validators: EthAddress[]): Promise<EthAddress[]>;
|
|
109
|
+
getProposerFromEpochCommittee(epochCommitteeInfo: EpochCommitteeInfo, slot: bigint): EthAddress | undefined;
|
|
110
|
+
/** Check if a validator is in the given slot's committee */
|
|
111
|
+
isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
|
|
112
|
+
/** From the set of given addresses, return all that are on the committee for the given slot */
|
|
113
|
+
filterInCommittee(slot: SlotTag, validators: EthAddress[]): Promise<EthAddress[]>;
|
|
114
|
+
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
108
115
|
}
|
|
109
116
|
//# sourceMappingURL=epoch_cache.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epoch_cache.d.ts","sourceRoot":"","sources":["../src/epoch_cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,cAAc,EAAuB,MAAM,iBAAiB,CAAC;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAEL,KAAK,iBAAiB,EAOvB,MAAM,6BAA6B,CAAC;AAIrC,OAAO,EAAE,KAAK,gBAAgB,EAA8B,MAAM,aAAa,CAAC;AAEhF,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,UAAU,EAAE,GAAG,SAAS,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"epoch_cache.d.ts","sourceRoot":"","sources":["../src/epoch_cache.ts"],"names":[],"mappings":"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"}
|
package/dest/epoch_cache.js
CHANGED
|
@@ -19,15 +19,20 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
19
19
|
dateProvider;
|
|
20
20
|
config;
|
|
21
21
|
cache;
|
|
22
|
+
allValidators;
|
|
23
|
+
lastValidatorRefresh;
|
|
22
24
|
log;
|
|
23
25
|
constructor(rollup, initialEpoch = 0n, initialValidators = undefined, initialSampleSeed = 0n, l1constants = EmptyL1RollupConstants, dateProvider = new DateProvider(), config = {
|
|
24
|
-
cacheSize: 12
|
|
26
|
+
cacheSize: 12,
|
|
27
|
+
validatorRefreshIntervalSeconds: 60
|
|
25
28
|
}){
|
|
26
29
|
this.rollup = rollup;
|
|
27
30
|
this.l1constants = l1constants;
|
|
28
31
|
this.dateProvider = dateProvider;
|
|
29
32
|
this.config = config;
|
|
30
33
|
this.cache = new Map();
|
|
34
|
+
this.allValidators = new Set();
|
|
35
|
+
this.lastValidatorRefresh = 0;
|
|
31
36
|
this.log = createLogger('epoch-cache');
|
|
32
37
|
this.cache.set(initialEpoch, {
|
|
33
38
|
epoch: initialEpoch,
|
|
@@ -222,21 +227,36 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
222
227
|
const proposerIndex = this.computeProposerIndex(slot, epoch, seed, BigInt(committee.length));
|
|
223
228
|
return committee[Number(proposerIndex)];
|
|
224
229
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
230
|
+
getProposerFromEpochCommittee(epochCommitteeInfo, slot) {
|
|
231
|
+
if (!epochCommitteeInfo.committee || epochCommitteeInfo.committee.length === 0) {
|
|
232
|
+
return undefined;
|
|
233
|
+
}
|
|
234
|
+
const proposerIndex = this.computeProposerIndex(slot, epochCommitteeInfo.epoch, epochCommitteeInfo.seed, BigInt(epochCommitteeInfo.committee.length));
|
|
235
|
+
return epochCommitteeInfo.committee[Number(proposerIndex)];
|
|
236
|
+
}
|
|
237
|
+
/** Check if a validator is in the given slot's committee */ async isInCommittee(slot, validator) {
|
|
238
|
+
const { committee } = await this.getCommittee(slot);
|
|
229
239
|
if (!committee) {
|
|
230
240
|
return false;
|
|
231
241
|
}
|
|
232
242
|
return committee.some((v)=>v.equals(validator));
|
|
233
243
|
}
|
|
234
|
-
async filterInCommittee(validators) {
|
|
235
|
-
const { committee } = await this.getCommittee();
|
|
244
|
+
/** From the set of given addresses, return all that are on the committee for the given slot */ async filterInCommittee(slot, validators) {
|
|
245
|
+
const { committee } = await this.getCommittee(slot);
|
|
236
246
|
if (!committee) {
|
|
237
247
|
return [];
|
|
238
248
|
}
|
|
239
249
|
const committeeSet = new Set(committee.map((v)=>v.toString()));
|
|
240
250
|
return validators.filter((v)=>committeeSet.has(v.toString()));
|
|
241
251
|
}
|
|
252
|
+
async getRegisteredValidators() {
|
|
253
|
+
const validatorRefreshIntervalMs = this.config.validatorRefreshIntervalSeconds * 1000;
|
|
254
|
+
const validatorRefreshTime = this.lastValidatorRefresh + validatorRefreshIntervalMs;
|
|
255
|
+
if (validatorRefreshTime < this.dateProvider.now()) {
|
|
256
|
+
const currentSet = await this.rollup.getAttesters();
|
|
257
|
+
this.allValidators = new Set(currentSet);
|
|
258
|
+
this.lastValidatorRefresh = this.dateProvider.now();
|
|
259
|
+
}
|
|
260
|
+
return Array.from(this.allValidators.keys().map((v)=>EthAddress.fromString(v)));
|
|
261
|
+
}
|
|
242
262
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/epoch-cache",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-nightly.20250814",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
"../package.common.json"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@aztec/ethereum": "
|
|
30
|
-
"@aztec/foundation": "
|
|
31
|
-
"@aztec/l1-artifacts": "
|
|
32
|
-
"@aztec/stdlib": "
|
|
29
|
+
"@aztec/ethereum": "2.0.0-nightly.20250814",
|
|
30
|
+
"@aztec/foundation": "2.0.0-nightly.20250814",
|
|
31
|
+
"@aztec/l1-artifacts": "2.0.0-nightly.20250814",
|
|
32
|
+
"@aztec/stdlib": "2.0.0-nightly.20250814",
|
|
33
33
|
"@viem/anvil": "^0.0.10",
|
|
34
34
|
"dotenv": "^16.0.3",
|
|
35
35
|
"get-port": "^7.1.0",
|
package/src/epoch_cache.ts
CHANGED
|
@@ -29,8 +29,10 @@ export type EpochCommitteeInfo = {
|
|
|
29
29
|
epoch: bigint;
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
+
export type SlotTag = 'now' | 'next' | bigint;
|
|
33
|
+
|
|
32
34
|
export interface EpochCacheInterface {
|
|
33
|
-
getCommittee(slot:
|
|
35
|
+
getCommittee(slot: SlotTag | undefined): Promise<EpochCommitteeInfo>;
|
|
34
36
|
getEpochAndSlotNow(): EpochAndSlot;
|
|
35
37
|
getEpochAndSlotInNextL1Slot(): EpochAndSlot & { now: bigint };
|
|
36
38
|
getProposerIndexEncoding(epoch: bigint, slot: bigint, seed: bigint): `0x${string}`;
|
|
@@ -41,7 +43,9 @@ export interface EpochCacheInterface {
|
|
|
41
43
|
currentSlot: bigint;
|
|
42
44
|
nextSlot: bigint;
|
|
43
45
|
}>;
|
|
44
|
-
|
|
46
|
+
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
47
|
+
isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
|
|
48
|
+
filterInCommittee(slot: SlotTag, validators: EthAddress[]): Promise<EthAddress[]>;
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
/**
|
|
@@ -55,6 +59,8 @@ export interface EpochCacheInterface {
|
|
|
55
59
|
*/
|
|
56
60
|
export class EpochCache implements EpochCacheInterface {
|
|
57
61
|
private cache: Map<bigint, EpochCommitteeInfo> = new Map();
|
|
62
|
+
private allValidators: Set<string> = new Set();
|
|
63
|
+
private lastValidatorRefresh = 0;
|
|
58
64
|
private readonly log: Logger = createLogger('epoch-cache');
|
|
59
65
|
|
|
60
66
|
constructor(
|
|
@@ -64,7 +70,7 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
64
70
|
initialSampleSeed: bigint = 0n,
|
|
65
71
|
private readonly l1constants: L1RollupConstants = EmptyL1RollupConstants,
|
|
66
72
|
private readonly dateProvider: DateProvider = new DateProvider(),
|
|
67
|
-
private readonly config = { cacheSize: 12 },
|
|
73
|
+
private readonly config = { cacheSize: 12, validatorRefreshIntervalSeconds: 60 },
|
|
68
74
|
) {
|
|
69
75
|
this.cache.set(initialEpoch, { epoch: initialEpoch, committee: initialValidators, seed: initialSampleSeed });
|
|
70
76
|
this.log.debug(`Initialized EpochCache with ${initialValidators?.length ?? 'no'} validators`, {
|
|
@@ -163,7 +169,7 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
163
169
|
* @param nextSlot - If true, get the validator set for the next slot.
|
|
164
170
|
* @returns The current validator set.
|
|
165
171
|
*/
|
|
166
|
-
public async getCommittee(slot:
|
|
172
|
+
public async getCommittee(slot: SlotTag = 'now'): Promise<EpochCommitteeInfo> {
|
|
167
173
|
const { epoch, ts } = this.getEpochAndTimestamp(slot);
|
|
168
174
|
|
|
169
175
|
if (this.cache.has(epoch)) {
|
|
@@ -185,7 +191,7 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
185
191
|
return epochData;
|
|
186
192
|
}
|
|
187
193
|
|
|
188
|
-
private getEpochAndTimestamp(slot:
|
|
194
|
+
private getEpochAndTimestamp(slot: SlotTag = 'now') {
|
|
189
195
|
if (slot === 'now') {
|
|
190
196
|
return this.getEpochAndSlotNow();
|
|
191
197
|
} else if (slot === 'next') {
|
|
@@ -216,7 +222,7 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
216
222
|
);
|
|
217
223
|
}
|
|
218
224
|
|
|
219
|
-
computeProposerIndex(slot: bigint, epoch: bigint, seed: bigint, size: bigint): bigint {
|
|
225
|
+
public computeProposerIndex(slot: bigint, epoch: bigint, seed: bigint, size: bigint): bigint {
|
|
220
226
|
// if committe size is 0, then mod 1 is 0
|
|
221
227
|
if (size === 0n) {
|
|
222
228
|
return 0n;
|
|
@@ -277,23 +283,47 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
277
283
|
return committee[Number(proposerIndex)];
|
|
278
284
|
}
|
|
279
285
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
const
|
|
286
|
+
public getProposerFromEpochCommittee(epochCommitteeInfo: EpochCommitteeInfo, slot: bigint): EthAddress | undefined {
|
|
287
|
+
if (!epochCommitteeInfo.committee || epochCommitteeInfo.committee.length === 0) {
|
|
288
|
+
return undefined;
|
|
289
|
+
}
|
|
290
|
+
const proposerIndex = this.computeProposerIndex(
|
|
291
|
+
slot,
|
|
292
|
+
epochCommitteeInfo.epoch,
|
|
293
|
+
epochCommitteeInfo.seed,
|
|
294
|
+
BigInt(epochCommitteeInfo.committee.length),
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
return epochCommitteeInfo.committee[Number(proposerIndex)];
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/** Check if a validator is in the given slot's committee */
|
|
301
|
+
async isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean> {
|
|
302
|
+
const { committee } = await this.getCommittee(slot);
|
|
285
303
|
if (!committee) {
|
|
286
304
|
return false;
|
|
287
305
|
}
|
|
288
306
|
return committee.some(v => v.equals(validator));
|
|
289
307
|
}
|
|
290
308
|
|
|
291
|
-
|
|
292
|
-
|
|
309
|
+
/** From the set of given addresses, return all that are on the committee for the given slot */
|
|
310
|
+
async filterInCommittee(slot: SlotTag, validators: EthAddress[]): Promise<EthAddress[]> {
|
|
311
|
+
const { committee } = await this.getCommittee(slot);
|
|
293
312
|
if (!committee) {
|
|
294
313
|
return [];
|
|
295
314
|
}
|
|
296
315
|
const committeeSet = new Set(committee.map(v => v.toString()));
|
|
297
316
|
return validators.filter(v => committeeSet.has(v.toString()));
|
|
298
317
|
}
|
|
318
|
+
|
|
319
|
+
async getRegisteredValidators(): Promise<EthAddress[]> {
|
|
320
|
+
const validatorRefreshIntervalMs = this.config.validatorRefreshIntervalSeconds * 1000;
|
|
321
|
+
const validatorRefreshTime = this.lastValidatorRefresh + validatorRefreshIntervalMs;
|
|
322
|
+
if (validatorRefreshTime < this.dateProvider.now()) {
|
|
323
|
+
const currentSet = await this.rollup.getAttesters();
|
|
324
|
+
this.allValidators = new Set(currentSet);
|
|
325
|
+
this.lastValidatorRefresh = this.dateProvider.now();
|
|
326
|
+
}
|
|
327
|
+
return Array.from(this.allValidators.keys().map(v => EthAddress.fromString(v)));
|
|
328
|
+
}
|
|
299
329
|
}
|