@aztec/epoch-cache 0.0.1-commit.1142ef1 → 0.0.1-commit.1bea0213
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 +26 -17
- package/dest/epoch_cache.d.ts.map +1 -1
- package/dest/epoch_cache.js +32 -14
- package/package.json +7 -7
- package/src/epoch_cache.ts +45 -26
package/dest/epoch_cache.d.ts
CHANGED
|
@@ -13,22 +13,24 @@ 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 {
|
|
19
21
|
getCommittee(slot: SlotTag | undefined): Promise<EpochCommitteeInfo>;
|
|
20
|
-
getEpochAndSlotNow(): EpochAndSlot
|
|
22
|
+
getEpochAndSlotNow(): EpochAndSlot & {
|
|
23
|
+
nowMs: bigint;
|
|
24
|
+
};
|
|
21
25
|
getEpochAndSlotInNextL1Slot(): EpochAndSlot & {
|
|
22
26
|
now: bigint;
|
|
23
27
|
};
|
|
24
28
|
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
|
|
25
29
|
computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
|
|
26
|
-
|
|
27
|
-
currentProposer: EthAddress | undefined;
|
|
28
|
-
nextProposer: EthAddress | undefined;
|
|
30
|
+
getCurrentAndNextSlot(): {
|
|
29
31
|
currentSlot: SlotNumber;
|
|
30
32
|
nextSlot: SlotNumber;
|
|
31
|
-
}
|
|
33
|
+
};
|
|
32
34
|
getProposerAttesterAddressInSlot(slot: SlotNumber): Promise<EthAddress | undefined>;
|
|
33
35
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
34
36
|
isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
|
|
@@ -67,7 +69,7 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
67
69
|
}): Promise<EpochCache>;
|
|
68
70
|
getL1Constants(): L1RollupConstants;
|
|
69
71
|
getEpochAndSlotNow(): EpochAndSlot & {
|
|
70
|
-
|
|
72
|
+
nowMs: bigint;
|
|
71
73
|
};
|
|
72
74
|
nowInSeconds(): bigint;
|
|
73
75
|
private getEpochAndSlotAtSlot;
|
|
@@ -76,6 +78,20 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
76
78
|
};
|
|
77
79
|
private getEpochAndSlotAtTimestamp;
|
|
78
80
|
getCommitteeForEpoch(epoch: EpochNumber): Promise<EpochCommitteeInfo>;
|
|
81
|
+
/**
|
|
82
|
+
* Returns whether the escape hatch is open for the given epoch.
|
|
83
|
+
*
|
|
84
|
+
* Uses the already-cached EpochCommitteeInfo when available. If not cached, it will fetch
|
|
85
|
+
* the epoch committee info (which includes the escape hatch flag) and return it.
|
|
86
|
+
*/
|
|
87
|
+
isEscapeHatchOpen(epoch: EpochNumber): Promise<boolean>;
|
|
88
|
+
/**
|
|
89
|
+
* Returns whether the escape hatch is open for the epoch containing the given slot.
|
|
90
|
+
*
|
|
91
|
+
* This is a lightweight helper intended for callers that already have a slot number and only
|
|
92
|
+
* need the escape hatch flag (without pulling full committee info).
|
|
93
|
+
*/
|
|
94
|
+
isEscapeHatchOpenAtSlot(slot?: SlotTag): Promise<boolean>;
|
|
79
95
|
/**
|
|
80
96
|
* Get the current validator set
|
|
81
97
|
* @param nextSlot - If true, get the validator set for the next slot.
|
|
@@ -89,18 +105,11 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
89
105
|
*/
|
|
90
106
|
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
|
|
91
107
|
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<{
|
|
108
|
+
/** Returns the current and next L2 slot numbers. */
|
|
109
|
+
getCurrentAndNextSlot(): {
|
|
99
110
|
currentSlot: SlotNumber;
|
|
100
111
|
nextSlot: SlotNumber;
|
|
101
|
-
|
|
102
|
-
nextProposer: EthAddress | undefined;
|
|
103
|
-
}>;
|
|
112
|
+
};
|
|
104
113
|
/**
|
|
105
114
|
* Get the proposer attester address in the given L2 slot
|
|
106
115
|
* @returns The proposer attester address. If the committee does not exist, we throw a NoCommitteeError.
|
|
@@ -121,4 +130,4 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
121
130
|
filterInCommittee(slot: SlotTag, validators: EthAddress[]): Promise<EthAddress[]>;
|
|
122
131
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
123
132
|
}
|
|
124
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
133
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXBvY2hfY2FjaGUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9lcG9jaF9jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQW9CLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDMUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEVBQ0wsS0FBSyxpQkFBaUIsRUFPdkIsTUFBTSw2QkFBNkIsQ0FBQztBQUlyQyxPQUFPLEVBQUUsS0FBSyxnQkFBZ0IsRUFBOEIsTUFBTSxhQUFhLENBQUM7QUFFaEYsTUFBTSxNQUFNLFlBQVksR0FBRztJQUN6QixLQUFLLEVBQUUsV0FBVyxDQUFDO0lBQ25CLElBQUksRUFBRSxVQUFVLENBQUM7SUFDakIsRUFBRSxFQUFFLE1BQU0sQ0FBQztDQUNaLENBQUM7QUFFRixNQUFNLE1BQU0sa0JBQWtCLEdBQUc7SUFDL0IsU0FBUyxFQUFFLFVBQVUsRUFBRSxHQUFHLFNBQVMsQ0FBQztJQUNwQyxJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ2IsS0FBSyxFQUFFLFdBQVcsQ0FBQztJQUNuQiwrREFBK0Q7SUFDL0QsaUJBQWlCLEVBQUUsT0FBTyxDQUFDO0NBQzVCLENBQUM7QUFFRixNQUFNLE1BQU0sT0FBTyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsVUFBVSxDQUFDO0FBRWxELE1BQU0sV0FBVyxtQkFBbUI7SUFDbEMsWUFBWSxDQUFDLElBQUksRUFBRSxPQUFPLEdBQUcsU0FBUyxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JFLGtCQUFrQixJQUFJLFlBQVksR0FBRztRQUFFLEtBQUssRUFBRSxNQUFNLENBQUE7S0FBRSxDQUFDO0lBQ3ZELDJCQUEyQixJQUFJLFlBQVksR0FBRztRQUFFLEdBQUcsRUFBRSxNQUFNLENBQUE7S0FBRSxDQUFDO0lBQzlELHdCQUF3QixDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsTUFBTSxHQUFHLEtBQUssTUFBTSxFQUFFLENBQUM7SUFDNUYsb0JBQW9CLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDL0YscUJBQXFCLElBQUk7UUFBRSxXQUFXLEVBQUUsVUFBVSxDQUFDO1FBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQTtLQUFFLENBQUM7SUFDM0UsZ0NBQWdDLENBQUMsSUFBSSxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0lBQ3BGLHVCQUF1QixJQUFJLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBQ2pELGFBQWEsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3RFLGlCQUFpQixDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO0NBQ25GO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxxQkFBYSxVQUFXLFlBQVcsbUJBQW1CO0lBUWxELE9BQU8sQ0FBQyxNQUFNO0lBQ2QsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXO0lBSTVCLE9BQU8sQ0FBQyxRQUFRLENBQUMsWUFBWTtJQUM3QixTQUFTLENBQUMsUUFBUSxDQUFDLE1BQU07Ozs7SUFaM0IsU0FBUyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsV0FBVyxFQUFFLGtCQUFrQixDQUFDLENBQWE7SUFDbEUsT0FBTyxDQUFDLGFBQWEsQ0FBMEI7SUFDL0MsT0FBTyxDQUFDLG9CQUFvQixDQUFLO0lBQ2pDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUF1QztJQUUzRCxZQUNVLE1BQU0sRUFBRSxjQUFjLEVBQ2IsV0FBVyxFQUFFLGlCQUFpQixHQUFHO1FBQ2hELDBCQUEwQixFQUFFLE1BQU0sQ0FBQztRQUNuQyxvQkFBb0IsRUFBRSxNQUFNLENBQUM7S0FDOUIsRUFDZ0IsWUFBWSxHQUFFLFlBQWlDLEVBQzdDLE1BQU07OztLQUF5RCxFQUtuRjtJQUVELE9BQWEsTUFBTSxDQUNqQixlQUFlLEVBQUUsVUFBVSxHQUFHLGNBQWMsRUFDNUMsTUFBTSxDQUFDLEVBQUUsZ0JBQWdCLEVBQ3pCLElBQUksR0FBRTtRQUFFLFlBQVksQ0FBQyxFQUFFLFlBQVksQ0FBQTtLQUFPLHVCQWdEM0M7SUFFTSxjQUFjLElBQUksaUJBQWlCLENBRXpDO0lBRU0sa0JBQWtCLElBQUksWUFBWSxHQUFHO1FBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQTtLQUFFLENBSTVEO0lBRU0sWUFBWSxJQUFJLE1BQU0sQ0FFNUI7SUFFRCxPQUFPLENBQUMscUJBQXFCO0lBTXRCLDJCQUEyQixJQUFJLFlBQVksR0FBRztRQUFFLEdBQUcsRUFBRSxNQUFNLENBQUE7S0FBRSxDQUluRTtJQUVELE9BQU8sQ0FBQywwQkFBMEI7SUFTM0Isb0JBQW9CLENBQUMsS0FBSyxFQUFFLFdBQVcsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FHM0U7SUFFRDs7Ozs7T0FLRztJQUNVLGlCQUFpQixDQUFDLEtBQUssRUFBRSxXQUFXLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQU9uRTtJQUVEOzs7OztPQUtHO0lBQ1UsdUJBQXVCLENBQUMsSUFBSSxHQUFFLE9BQWUsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBUzVFO0lBRUQ7Ozs7T0FJRztJQUNVLFlBQVksQ0FBQyxJQUFJLEdBQUUsT0FBZSxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQW9CNUU7SUFFRCxPQUFPLENBQUMsb0JBQW9CO1lBVWQsZ0JBQWdCO0lBa0I5Qjs7T0FFRztJQUNILHdCQUF3QixDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsTUFBTSxHQUFHLEtBQUssTUFBTSxFQUFFLENBUzFGO0lBRU0sb0JBQW9CLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sR0FBRyxNQUFNLENBTXBHO0lBRUQsb0RBQW9EO0lBQzdDLHFCQUFxQixJQUFJO1FBQUUsV0FBVyxFQUFFLFVBQVUsQ0FBQztRQUFDLFFBQVEsRUFBRSxVQUFVLENBQUE7S0FBRSxDQVFoRjtJQUVEOzs7O09BSUc7SUFDSSxnQ0FBZ0MsQ0FBQyxJQUFJLEVBQUUsVUFBVSxHQUFHLE9BQU8sQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBR3pGO0lBRUQ7Ozs7T0FJRztJQUNJLG9DQUFvQyxJQUFJLE9BQU8sQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBRzdFO1lBUWEsNEJBQTRCO0lBYW5DLDZCQUE2QixDQUNsQyxrQkFBa0IsRUFBRSxrQkFBa0IsRUFDdEMsSUFBSSxFQUFFLFVBQVUsR0FDZixVQUFVLEdBQUcsU0FBUyxDQVl4QjtJQUVELDREQUE0RDtJQUN0RCxhQUFhLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FNMUU7SUFFRCwrRkFBK0Y7SUFDekYsaUJBQWlCLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLEdBQUcsT0FBTyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBT3RGO0lBRUssdUJBQXVCLElBQUksT0FBTyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBU3JEO0NBQ0YifQ==
|
|
@@ -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
|
@@ -82,10 +82,11 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
82
82
|
return this.l1constants;
|
|
83
83
|
}
|
|
84
84
|
getEpochAndSlotNow() {
|
|
85
|
-
const
|
|
85
|
+
const nowMs = BigInt(this.dateProvider.now());
|
|
86
|
+
const nowSeconds = nowMs / 1000n;
|
|
86
87
|
return {
|
|
87
|
-
...this.getEpochAndSlotAtTimestamp(
|
|
88
|
-
|
|
88
|
+
...this.getEpochAndSlotAtTimestamp(nowSeconds),
|
|
89
|
+
nowMs
|
|
89
90
|
};
|
|
90
91
|
}
|
|
91
92
|
nowInSeconds() {
|
|
@@ -121,6 +122,28 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
121
122
|
return this.getCommittee(startSlot);
|
|
122
123
|
}
|
|
123
124
|
/**
|
|
125
|
+
* Returns whether the escape hatch is open for the given epoch.
|
|
126
|
+
*
|
|
127
|
+
* Uses the already-cached EpochCommitteeInfo when available. If not cached, it will fetch
|
|
128
|
+
* the epoch committee info (which includes the escape hatch flag) and return it.
|
|
129
|
+
*/ async isEscapeHatchOpen(epoch) {
|
|
130
|
+
const cached = this.cache.get(epoch);
|
|
131
|
+
if (cached) {
|
|
132
|
+
return cached.isEscapeHatchOpen;
|
|
133
|
+
}
|
|
134
|
+
const info = await this.getCommitteeForEpoch(epoch);
|
|
135
|
+
return info.isEscapeHatchOpen;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Returns whether the escape hatch is open for the epoch containing the given slot.
|
|
139
|
+
*
|
|
140
|
+
* This is a lightweight helper intended for callers that already have a slot number and only
|
|
141
|
+
* need the escape hatch flag (without pulling full committee info).
|
|
142
|
+
*/ async isEscapeHatchOpenAtSlot(slot = 'now') {
|
|
143
|
+
const epoch = slot === 'now' ? this.getEpochAndSlotNow().epoch : slot === 'next' ? this.getEpochAndSlotInNextL1Slot().epoch : getEpochAtSlot(slot, this.l1constants);
|
|
144
|
+
return await this.isEscapeHatchOpen(epoch);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
124
147
|
* Get the current validator set
|
|
125
148
|
* @param nextSlot - If true, get the validator set for the next slot.
|
|
126
149
|
* @returns The current validator set.
|
|
@@ -153,12 +176,13 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
153
176
|
}
|
|
154
177
|
async computeCommittee(when) {
|
|
155
178
|
const { ts, epoch } = when;
|
|
156
|
-
const [committee, seedBuffer, l1Timestamp] = await Promise.all([
|
|
179
|
+
const [committee, seedBuffer, l1Timestamp, isEscapeHatchOpen] = await Promise.all([
|
|
157
180
|
this.rollup.getCommitteeAt(ts),
|
|
158
181
|
this.rollup.getSampleSeedAt(ts),
|
|
159
182
|
this.rollup.client.getBlock({
|
|
160
183
|
includeTransactions: false
|
|
161
|
-
}).then((b)=>b.timestamp)
|
|
184
|
+
}).then((b)=>b.timestamp),
|
|
185
|
+
this.rollup.isEscapeHatchOpen(epoch)
|
|
162
186
|
]);
|
|
163
187
|
const { lagInEpochsForValidatorSet, epochDuration, slotDuration } = this.l1constants;
|
|
164
188
|
const sub = BigInt(lagInEpochsForValidatorSet) * BigInt(epochDuration) * BigInt(slotDuration);
|
|
@@ -168,7 +192,8 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
168
192
|
return {
|
|
169
193
|
committee,
|
|
170
194
|
seed: seedBuffer.toBigInt(),
|
|
171
|
-
epoch
|
|
195
|
+
epoch,
|
|
196
|
+
isEscapeHatchOpen
|
|
172
197
|
};
|
|
173
198
|
}
|
|
174
199
|
/**
|
|
@@ -200,17 +225,10 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
200
225
|
}
|
|
201
226
|
return BigInt(keccak256(this.getProposerIndexEncoding(epoch, slot, seed))) % size;
|
|
202
227
|
}
|
|
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() {
|
|
228
|
+
/** Returns the current and next L2 slot numbers. */ getCurrentAndNextSlot() {
|
|
209
229
|
const current = this.getEpochAndSlotNow();
|
|
210
230
|
const next = this.getEpochAndSlotInNextL1Slot();
|
|
211
231
|
return {
|
|
212
|
-
currentProposer: await this.getProposerAttesterAddressAt(current),
|
|
213
|
-
nextProposer: await this.getProposerAttesterAddressAt(next),
|
|
214
232
|
currentSlot: current.slot,
|
|
215
233
|
nextSlot: next.slot
|
|
216
234
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/epoch-cache",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.1bea0213",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"build": "yarn clean && ../scripts/tsc.sh",
|
|
19
19
|
"build:dev": "../scripts/tsc.sh --watch",
|
|
20
20
|
"clean": "rm -rf ./dest .tsbuildinfo",
|
|
21
|
-
"start:dev": "concurrently -k \"
|
|
21
|
+
"start:dev": "concurrently -k \"../scripts/tsc.sh --watch\" \"nodemon --watch dest --exec yarn start\"",
|
|
22
22
|
"start": "node ./dest/index.js",
|
|
23
23
|
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
|
|
24
24
|
},
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
"../package.common.json"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
30
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
31
|
-
"@aztec/l1-artifacts": "0.0.1-commit.
|
|
32
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
29
|
+
"@aztec/ethereum": "0.0.1-commit.1bea0213",
|
|
30
|
+
"@aztec/foundation": "0.0.1-commit.1bea0213",
|
|
31
|
+
"@aztec/l1-artifacts": "0.0.1-commit.1bea0213",
|
|
32
|
+
"@aztec/stdlib": "0.0.1-commit.1bea0213",
|
|
33
33
|
"@viem/anvil": "^0.0.10",
|
|
34
34
|
"dotenv": "^16.0.3",
|
|
35
35
|
"get-port": "^7.1.0",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@jest/globals": "^30.0.0",
|
|
43
43
|
"@types/jest": "^30.0.0",
|
|
44
44
|
"@types/node": "^22.15.17",
|
|
45
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
45
|
+
"@typescript/native-preview": "7.0.0-dev.20260113.1",
|
|
46
46
|
"jest": "^30.0.0",
|
|
47
47
|
"ts-node": "^10.9.1",
|
|
48
48
|
"typescript": "^5.3.3"
|
package/src/epoch_cache.ts
CHANGED
|
@@ -28,22 +28,19 @@ 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;
|
|
34
36
|
|
|
35
37
|
export interface EpochCacheInterface {
|
|
36
38
|
getCommittee(slot: SlotTag | undefined): Promise<EpochCommitteeInfo>;
|
|
37
|
-
getEpochAndSlotNow(): EpochAndSlot;
|
|
39
|
+
getEpochAndSlotNow(): EpochAndSlot & { nowMs: bigint };
|
|
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>;
|
|
@@ -137,9 +134,10 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
137
134
|
return this.l1constants;
|
|
138
135
|
}
|
|
139
136
|
|
|
140
|
-
public getEpochAndSlotNow(): EpochAndSlot & {
|
|
141
|
-
const
|
|
142
|
-
|
|
137
|
+
public getEpochAndSlotNow(): EpochAndSlot & { nowMs: bigint } {
|
|
138
|
+
const nowMs = BigInt(this.dateProvider.now());
|
|
139
|
+
const nowSeconds = nowMs / 1000n;
|
|
140
|
+
return { ...this.getEpochAndSlotAtTimestamp(nowSeconds), nowMs };
|
|
143
141
|
}
|
|
144
142
|
|
|
145
143
|
public nowInSeconds(): bigint {
|
|
@@ -172,6 +170,38 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
172
170
|
return this.getCommittee(startSlot);
|
|
173
171
|
}
|
|
174
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Returns whether the escape hatch is open for the given epoch.
|
|
175
|
+
*
|
|
176
|
+
* Uses the already-cached EpochCommitteeInfo when available. If not cached, it will fetch
|
|
177
|
+
* the epoch committee info (which includes the escape hatch flag) and return it.
|
|
178
|
+
*/
|
|
179
|
+
public async isEscapeHatchOpen(epoch: EpochNumber): Promise<boolean> {
|
|
180
|
+
const cached = this.cache.get(epoch);
|
|
181
|
+
if (cached) {
|
|
182
|
+
return cached.isEscapeHatchOpen;
|
|
183
|
+
}
|
|
184
|
+
const info = await this.getCommitteeForEpoch(epoch);
|
|
185
|
+
return info.isEscapeHatchOpen;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Returns whether the escape hatch is open for the epoch containing the given slot.
|
|
190
|
+
*
|
|
191
|
+
* This is a lightweight helper intended for callers that already have a slot number and only
|
|
192
|
+
* need the escape hatch flag (without pulling full committee info).
|
|
193
|
+
*/
|
|
194
|
+
public async isEscapeHatchOpenAtSlot(slot: SlotTag = 'now'): Promise<boolean> {
|
|
195
|
+
const epoch =
|
|
196
|
+
slot === 'now'
|
|
197
|
+
? this.getEpochAndSlotNow().epoch
|
|
198
|
+
: slot === 'next'
|
|
199
|
+
? this.getEpochAndSlotInNextL1Slot().epoch
|
|
200
|
+
: getEpochAtSlot(slot, this.l1constants);
|
|
201
|
+
|
|
202
|
+
return await this.isEscapeHatchOpen(epoch);
|
|
203
|
+
}
|
|
204
|
+
|
|
175
205
|
/**
|
|
176
206
|
* Get the current validator set
|
|
177
207
|
* @param nextSlot - If true, get the validator set for the next slot.
|
|
@@ -211,10 +241,11 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
211
241
|
|
|
212
242
|
private async computeCommittee(when: { epoch: EpochNumber; ts: bigint }): Promise<EpochCommitteeInfo> {
|
|
213
243
|
const { ts, epoch } = when;
|
|
214
|
-
const [committee, seedBuffer, l1Timestamp] = await Promise.all([
|
|
244
|
+
const [committee, seedBuffer, l1Timestamp, isEscapeHatchOpen] = await Promise.all([
|
|
215
245
|
this.rollup.getCommitteeAt(ts),
|
|
216
246
|
this.rollup.getSampleSeedAt(ts),
|
|
217
247
|
this.rollup.client.getBlock({ includeTransactions: false }).then(b => b.timestamp),
|
|
248
|
+
this.rollup.isEscapeHatchOpen(epoch),
|
|
218
249
|
]);
|
|
219
250
|
const { lagInEpochsForValidatorSet, epochDuration, slotDuration } = this.l1constants;
|
|
220
251
|
const sub = BigInt(lagInEpochsForValidatorSet) * BigInt(epochDuration) * BigInt(slotDuration);
|
|
@@ -223,7 +254,7 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
223
254
|
`Cannot query committee for future epoch ${epoch} with timestamp ${ts} (current L1 time is ${l1Timestamp}). Check your Ethereum node is synced.`,
|
|
224
255
|
);
|
|
225
256
|
}
|
|
226
|
-
return { committee, seed: seedBuffer.toBigInt(), epoch };
|
|
257
|
+
return { committee, seed: seedBuffer.toBigInt(), epoch, isEscapeHatchOpen };
|
|
227
258
|
}
|
|
228
259
|
|
|
229
260
|
/**
|
|
@@ -248,24 +279,12 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
248
279
|
return BigInt(keccak256(this.getProposerIndexEncoding(epoch, slot, seed))) % size;
|
|
249
280
|
}
|
|
250
281
|
|
|
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
|
-
}> {
|
|
282
|
+
/** Returns the current and next L2 slot numbers. */
|
|
283
|
+
public getCurrentAndNextSlot(): { currentSlot: SlotNumber; nextSlot: SlotNumber } {
|
|
263
284
|
const current = this.getEpochAndSlotNow();
|
|
264
285
|
const next = this.getEpochAndSlotInNextL1Slot();
|
|
265
286
|
|
|
266
287
|
return {
|
|
267
|
-
currentProposer: await this.getProposerAttesterAddressAt(current),
|
|
268
|
-
nextProposer: await this.getProposerAttesterAddressAt(next),
|
|
269
288
|
currentSlot: current.slot,
|
|
270
289
|
nextSlot: next.slot,
|
|
271
290
|
};
|