@aztec/epoch-cache 4.0.0-nightly.20260119 → 4.0.0-nightly.20260121
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 +22 -15
- package/dest/epoch_cache.d.ts.map +1 -1
- package/dest/epoch_cache.js +28 -11
- package/package.json +5 -5
- package/src/epoch_cache.ts +40 -22
package/dest/epoch_cache.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export type EpochCommitteeInfo = {
|
|
|
13
13
|
committee: EthAddress[] | undefined;
|
|
14
14
|
seed: bigint;
|
|
15
15
|
epoch: EpochNumber;
|
|
16
|
+
/** True if the epoch is within an open escape hatch window. */
|
|
17
|
+
isEscapeHatchOpen: boolean;
|
|
16
18
|
};
|
|
17
19
|
export type SlotTag = 'now' | 'next' | SlotNumber;
|
|
18
20
|
export interface EpochCacheInterface {
|
|
@@ -23,12 +25,10 @@ export interface EpochCacheInterface {
|
|
|
23
25
|
};
|
|
24
26
|
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
|
|
25
27
|
computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
|
|
26
|
-
|
|
27
|
-
currentProposer: EthAddress | undefined;
|
|
28
|
-
nextProposer: EthAddress | undefined;
|
|
28
|
+
getCurrentAndNextSlot(): {
|
|
29
29
|
currentSlot: SlotNumber;
|
|
30
30
|
nextSlot: SlotNumber;
|
|
31
|
-
}
|
|
31
|
+
};
|
|
32
32
|
getProposerAttesterAddressInSlot(slot: SlotNumber): Promise<EthAddress | undefined>;
|
|
33
33
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
34
34
|
isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
|
|
@@ -76,6 +76,20 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
76
76
|
};
|
|
77
77
|
private getEpochAndSlotAtTimestamp;
|
|
78
78
|
getCommitteeForEpoch(epoch: EpochNumber): Promise<EpochCommitteeInfo>;
|
|
79
|
+
/**
|
|
80
|
+
* Returns whether the escape hatch is open for the given epoch.
|
|
81
|
+
*
|
|
82
|
+
* Uses the already-cached EpochCommitteeInfo when available. If not cached, it will fetch
|
|
83
|
+
* the epoch committee info (which includes the escape hatch flag) and return it.
|
|
84
|
+
*/
|
|
85
|
+
isEscapeHatchOpen(epoch: EpochNumber): Promise<boolean>;
|
|
86
|
+
/**
|
|
87
|
+
* Returns whether the escape hatch is open for the epoch containing the given slot.
|
|
88
|
+
*
|
|
89
|
+
* This is a lightweight helper intended for callers that already have a slot number and only
|
|
90
|
+
* need the escape hatch flag (without pulling full committee info).
|
|
91
|
+
*/
|
|
92
|
+
isEscapeHatchOpenAtSlot(slot?: SlotTag): Promise<boolean>;
|
|
79
93
|
/**
|
|
80
94
|
* Get the current validator set
|
|
81
95
|
* @param nextSlot - If true, get the validator set for the next slot.
|
|
@@ -89,18 +103,11 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
89
103
|
*/
|
|
90
104
|
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
|
|
91
105
|
computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
|
|
92
|
-
/**
|
|
93
|
-
|
|
94
|
-
*
|
|
95
|
-
* We return the next proposer's attester address as the node will check if it is the proposer at the next ethereum block,
|
|
96
|
-
* which can be the next slot. If this is the case, then it will send proposals early.
|
|
97
|
-
*/
|
|
98
|
-
getProposerAttesterAddressInCurrentOrNextSlot(): Promise<{
|
|
106
|
+
/** Returns the current and next L2 slot numbers. */
|
|
107
|
+
getCurrentAndNextSlot(): {
|
|
99
108
|
currentSlot: SlotNumber;
|
|
100
109
|
nextSlot: SlotNumber;
|
|
101
|
-
|
|
102
|
-
nextProposer: EthAddress | undefined;
|
|
103
|
-
}>;
|
|
110
|
+
};
|
|
104
111
|
/**
|
|
105
112
|
* Get the proposer attester address in the given L2 slot
|
|
106
113
|
* @returns The proposer attester address. If the committee does not exist, we throw a NoCommitteeError.
|
|
@@ -121,4 +128,4 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
121
128
|
filterInCommittee(slot: SlotTag, validators: EthAddress[]): Promise<EthAddress[]>;
|
|
122
129
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
123
130
|
}
|
|
124
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
131
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXBvY2hfY2FjaGUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9lcG9jaF9jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQW9CLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDMUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEVBQ0wsS0FBSyxpQkFBaUIsRUFPdkIsTUFBTSw2QkFBNkIsQ0FBQztBQUlyQyxPQUFPLEVBQUUsS0FBSyxnQkFBZ0IsRUFBOEIsTUFBTSxhQUFhLENBQUM7QUFFaEYsTUFBTSxNQUFNLFlBQVksR0FBRztJQUN6QixLQUFLLEVBQUUsV0FBVyxDQUFDO0lBQ25CLElBQUksRUFBRSxVQUFVLENBQUM7SUFDakIsRUFBRSxFQUFFLE1BQU0sQ0FBQztDQUNaLENBQUM7QUFFRixNQUFNLE1BQU0sa0JBQWtCLEdBQUc7SUFDL0IsU0FBUyxFQUFFLFVBQVUsRUFBRSxHQUFHLFNBQVMsQ0FBQztJQUNwQyxJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ2IsS0FBSyxFQUFFLFdBQVcsQ0FBQztJQUNuQiwrREFBK0Q7SUFDL0QsaUJBQWlCLEVBQUUsT0FBTyxDQUFDO0NBQzVCLENBQUM7QUFFRixNQUFNLE1BQU0sT0FBTyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsVUFBVSxDQUFDO0FBRWxELE1BQU0sV0FBVyxtQkFBbUI7SUFDbEMsWUFBWSxDQUFDLElBQUksRUFBRSxPQUFPLEdBQUcsU0FBUyxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JFLGtCQUFrQixJQUFJLFlBQVksQ0FBQztJQUNuQywyQkFBMkIsSUFBSSxZQUFZLEdBQUc7UUFBRSxHQUFHLEVB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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epoch_cache.d.ts","sourceRoot":"","sources":["../src/epoch_cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EACL,KAAK,iBAAiB,EAOvB,MAAM,6BAA6B,CAAC;AAIrC,OAAO,EAAE,KAAK,gBAAgB,EAA8B,MAAM,aAAa,CAAC;AAEhF,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,EAAE,UAAU,CAAC;IACjB,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,WAAW,CAAC;
|
|
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
|
@@ -121,6 +121,28 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
121
121
|
return this.getCommittee(startSlot);
|
|
122
122
|
}
|
|
123
123
|
/**
|
|
124
|
+
* Returns whether the escape hatch is open for the given epoch.
|
|
125
|
+
*
|
|
126
|
+
* Uses the already-cached EpochCommitteeInfo when available. If not cached, it will fetch
|
|
127
|
+
* the epoch committee info (which includes the escape hatch flag) and return it.
|
|
128
|
+
*/ async isEscapeHatchOpen(epoch) {
|
|
129
|
+
const cached = this.cache.get(epoch);
|
|
130
|
+
if (cached) {
|
|
131
|
+
return cached.isEscapeHatchOpen;
|
|
132
|
+
}
|
|
133
|
+
const info = await this.getCommitteeForEpoch(epoch);
|
|
134
|
+
return info.isEscapeHatchOpen;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Returns whether the escape hatch is open for the epoch containing the given slot.
|
|
138
|
+
*
|
|
139
|
+
* This is a lightweight helper intended for callers that already have a slot number and only
|
|
140
|
+
* need the escape hatch flag (without pulling full committee info).
|
|
141
|
+
*/ async isEscapeHatchOpenAtSlot(slot = 'now') {
|
|
142
|
+
const epoch = slot === 'now' ? this.getEpochAndSlotNow().epoch : slot === 'next' ? this.getEpochAndSlotInNextL1Slot().epoch : getEpochAtSlot(slot, this.l1constants);
|
|
143
|
+
return await this.isEscapeHatchOpen(epoch);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
124
146
|
* Get the current validator set
|
|
125
147
|
* @param nextSlot - If true, get the validator set for the next slot.
|
|
126
148
|
* @returns The current validator set.
|
|
@@ -153,12 +175,13 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
153
175
|
}
|
|
154
176
|
async computeCommittee(when) {
|
|
155
177
|
const { ts, epoch } = when;
|
|
156
|
-
const [committee, seedBuffer, l1Timestamp] = await Promise.all([
|
|
178
|
+
const [committee, seedBuffer, l1Timestamp, isEscapeHatchOpen] = await Promise.all([
|
|
157
179
|
this.rollup.getCommitteeAt(ts),
|
|
158
180
|
this.rollup.getSampleSeedAt(ts),
|
|
159
181
|
this.rollup.client.getBlock({
|
|
160
182
|
includeTransactions: false
|
|
161
|
-
}).then((b)=>b.timestamp)
|
|
183
|
+
}).then((b)=>b.timestamp),
|
|
184
|
+
this.rollup.isEscapeHatchOpen(epoch)
|
|
162
185
|
]);
|
|
163
186
|
const { lagInEpochsForValidatorSet, epochDuration, slotDuration } = this.l1constants;
|
|
164
187
|
const sub = BigInt(lagInEpochsForValidatorSet) * BigInt(epochDuration) * BigInt(slotDuration);
|
|
@@ -168,7 +191,8 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
168
191
|
return {
|
|
169
192
|
committee,
|
|
170
193
|
seed: seedBuffer.toBigInt(),
|
|
171
|
-
epoch
|
|
194
|
+
epoch,
|
|
195
|
+
isEscapeHatchOpen
|
|
172
196
|
};
|
|
173
197
|
}
|
|
174
198
|
/**
|
|
@@ -200,17 +224,10 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
200
224
|
}
|
|
201
225
|
return BigInt(keccak256(this.getProposerIndexEncoding(epoch, slot, seed))) % size;
|
|
202
226
|
}
|
|
203
|
-
/**
|
|
204
|
-
* Returns the current and next proposer's attester address
|
|
205
|
-
*
|
|
206
|
-
* We return the next proposer's attester address as the node will check if it is the proposer at the next ethereum block,
|
|
207
|
-
* which can be the next slot. If this is the case, then it will send proposals early.
|
|
208
|
-
*/ async getProposerAttesterAddressInCurrentOrNextSlot() {
|
|
227
|
+
/** Returns the current and next L2 slot numbers. */ getCurrentAndNextSlot() {
|
|
209
228
|
const current = this.getEpochAndSlotNow();
|
|
210
229
|
const next = this.getEpochAndSlotInNextL1Slot();
|
|
211
230
|
return {
|
|
212
|
-
currentProposer: await this.getProposerAttesterAddressAt(current),
|
|
213
|
-
nextProposer: await this.getProposerAttesterAddressAt(next),
|
|
214
231
|
currentSlot: current.slot,
|
|
215
232
|
nextSlot: next.slot
|
|
216
233
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/epoch-cache",
|
|
3
|
-
"version": "4.0.0-nightly.
|
|
3
|
+
"version": "4.0.0-nightly.20260121",
|
|
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": "4.0.0-nightly.
|
|
30
|
-
"@aztec/foundation": "4.0.0-nightly.
|
|
31
|
-
"@aztec/l1-artifacts": "4.0.0-nightly.
|
|
32
|
-
"@aztec/stdlib": "4.0.0-nightly.
|
|
29
|
+
"@aztec/ethereum": "4.0.0-nightly.20260121",
|
|
30
|
+
"@aztec/foundation": "4.0.0-nightly.20260121",
|
|
31
|
+
"@aztec/l1-artifacts": "4.0.0-nightly.20260121",
|
|
32
|
+
"@aztec/stdlib": "4.0.0-nightly.20260121",
|
|
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
|
@@ -28,6 +28,8 @@ export type EpochCommitteeInfo = {
|
|
|
28
28
|
committee: EthAddress[] | undefined;
|
|
29
29
|
seed: bigint;
|
|
30
30
|
epoch: EpochNumber;
|
|
31
|
+
/** True if the epoch is within an open escape hatch window. */
|
|
32
|
+
isEscapeHatchOpen: boolean;
|
|
31
33
|
};
|
|
32
34
|
|
|
33
35
|
export type SlotTag = 'now' | 'next' | SlotNumber;
|
|
@@ -38,12 +40,7 @@ export interface EpochCacheInterface {
|
|
|
38
40
|
getEpochAndSlotInNextL1Slot(): EpochAndSlot & { now: bigint };
|
|
39
41
|
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
|
|
40
42
|
computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
|
|
41
|
-
|
|
42
|
-
currentProposer: EthAddress | undefined;
|
|
43
|
-
nextProposer: EthAddress | undefined;
|
|
44
|
-
currentSlot: SlotNumber;
|
|
45
|
-
nextSlot: SlotNumber;
|
|
46
|
-
}>;
|
|
43
|
+
getCurrentAndNextSlot(): { currentSlot: SlotNumber; nextSlot: SlotNumber };
|
|
47
44
|
getProposerAttesterAddressInSlot(slot: SlotNumber): Promise<EthAddress | undefined>;
|
|
48
45
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
49
46
|
isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
|
|
@@ -172,6 +169,38 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
172
169
|
return this.getCommittee(startSlot);
|
|
173
170
|
}
|
|
174
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Returns whether the escape hatch is open for the given epoch.
|
|
174
|
+
*
|
|
175
|
+
* Uses the already-cached EpochCommitteeInfo when available. If not cached, it will fetch
|
|
176
|
+
* the epoch committee info (which includes the escape hatch flag) and return it.
|
|
177
|
+
*/
|
|
178
|
+
public async isEscapeHatchOpen(epoch: EpochNumber): Promise<boolean> {
|
|
179
|
+
const cached = this.cache.get(epoch);
|
|
180
|
+
if (cached) {
|
|
181
|
+
return cached.isEscapeHatchOpen;
|
|
182
|
+
}
|
|
183
|
+
const info = await this.getCommitteeForEpoch(epoch);
|
|
184
|
+
return info.isEscapeHatchOpen;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Returns whether the escape hatch is open for the epoch containing the given slot.
|
|
189
|
+
*
|
|
190
|
+
* This is a lightweight helper intended for callers that already have a slot number and only
|
|
191
|
+
* need the escape hatch flag (without pulling full committee info).
|
|
192
|
+
*/
|
|
193
|
+
public async isEscapeHatchOpenAtSlot(slot: SlotTag = 'now'): Promise<boolean> {
|
|
194
|
+
const epoch =
|
|
195
|
+
slot === 'now'
|
|
196
|
+
? this.getEpochAndSlotNow().epoch
|
|
197
|
+
: slot === 'next'
|
|
198
|
+
? this.getEpochAndSlotInNextL1Slot().epoch
|
|
199
|
+
: getEpochAtSlot(slot, this.l1constants);
|
|
200
|
+
|
|
201
|
+
return await this.isEscapeHatchOpen(epoch);
|
|
202
|
+
}
|
|
203
|
+
|
|
175
204
|
/**
|
|
176
205
|
* Get the current validator set
|
|
177
206
|
* @param nextSlot - If true, get the validator set for the next slot.
|
|
@@ -211,10 +240,11 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
211
240
|
|
|
212
241
|
private async computeCommittee(when: { epoch: EpochNumber; ts: bigint }): Promise<EpochCommitteeInfo> {
|
|
213
242
|
const { ts, epoch } = when;
|
|
214
|
-
const [committee, seedBuffer, l1Timestamp] = await Promise.all([
|
|
243
|
+
const [committee, seedBuffer, l1Timestamp, isEscapeHatchOpen] = await Promise.all([
|
|
215
244
|
this.rollup.getCommitteeAt(ts),
|
|
216
245
|
this.rollup.getSampleSeedAt(ts),
|
|
217
246
|
this.rollup.client.getBlock({ includeTransactions: false }).then(b => b.timestamp),
|
|
247
|
+
this.rollup.isEscapeHatchOpen(epoch),
|
|
218
248
|
]);
|
|
219
249
|
const { lagInEpochsForValidatorSet, epochDuration, slotDuration } = this.l1constants;
|
|
220
250
|
const sub = BigInt(lagInEpochsForValidatorSet) * BigInt(epochDuration) * BigInt(slotDuration);
|
|
@@ -223,7 +253,7 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
223
253
|
`Cannot query committee for future epoch ${epoch} with timestamp ${ts} (current L1 time is ${l1Timestamp}). Check your Ethereum node is synced.`,
|
|
224
254
|
);
|
|
225
255
|
}
|
|
226
|
-
return { committee, seed: seedBuffer.toBigInt(), epoch };
|
|
256
|
+
return { committee, seed: seedBuffer.toBigInt(), epoch, isEscapeHatchOpen };
|
|
227
257
|
}
|
|
228
258
|
|
|
229
259
|
/**
|
|
@@ -248,24 +278,12 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
248
278
|
return BigInt(keccak256(this.getProposerIndexEncoding(epoch, slot, seed))) % size;
|
|
249
279
|
}
|
|
250
280
|
|
|
251
|
-
/**
|
|
252
|
-
|
|
253
|
-
*
|
|
254
|
-
* We return the next proposer's attester address as the node will check if it is the proposer at the next ethereum block,
|
|
255
|
-
* which can be the next slot. If this is the case, then it will send proposals early.
|
|
256
|
-
*/
|
|
257
|
-
public async getProposerAttesterAddressInCurrentOrNextSlot(): Promise<{
|
|
258
|
-
currentSlot: SlotNumber;
|
|
259
|
-
nextSlot: SlotNumber;
|
|
260
|
-
currentProposer: EthAddress | undefined;
|
|
261
|
-
nextProposer: EthAddress | undefined;
|
|
262
|
-
}> {
|
|
281
|
+
/** Returns the current and next L2 slot numbers. */
|
|
282
|
+
public getCurrentAndNextSlot(): { currentSlot: SlotNumber; nextSlot: SlotNumber } {
|
|
263
283
|
const current = this.getEpochAndSlotNow();
|
|
264
284
|
const next = this.getEpochAndSlotInNextL1Slot();
|
|
265
285
|
|
|
266
286
|
return {
|
|
267
|
-
currentProposer: await this.getProposerAttesterAddressAt(current),
|
|
268
|
-
nextProposer: await this.getProposerAttesterAddressAt(next),
|
|
269
287
|
currentSlot: current.slot,
|
|
270
288
|
nextSlot: next.slot,
|
|
271
289
|
};
|