@aztec/epoch-cache 0.0.1-commit.b655e406 → 0.0.1-commit.fce3e4f
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/config.d.ts +1 -1
- package/dest/epoch_cache.d.ts +22 -24
- package/dest/epoch_cache.d.ts.map +1 -1
- package/dest/epoch_cache.js +22 -9
- package/dest/index.d.ts +1 -1
- package/package.json +10 -9
- package/src/epoch_cache.ts +54 -24
package/dest/config.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type L1ContractsConfig, type L1ReaderConfig } from '@aztec/ethereum';
|
|
2
2
|
export type EpochCacheConfig = Pick<L1ReaderConfig & L1ContractsConfig, 'l1RpcUrls' | 'l1ChainId' | 'viemPollingIntervalMS' | 'ethereumSlotDuration'>;
|
|
3
3
|
export declare function getEpochCacheConfigEnvVars(): EpochCacheConfig;
|
|
4
|
-
//# sourceMappingURL=
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxLQUFLLGlCQUFpQixFQUN0QixLQUFLLGNBQWMsRUFHcEIsTUFBTSxpQkFBaUIsQ0FBQztBQUV6QixNQUFNLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUNqQyxjQUFjLEdBQUcsaUJBQWlCLEVBQ2xDLFdBQVcsR0FBRyxXQUFXLEdBQUcsdUJBQXVCLEdBQUcsc0JBQXNCLENBQzdFLENBQUM7QUFFRix3QkFBZ0IsMEJBQTBCLElBQUksZ0JBQWdCLENBRTdEIn0=
|
package/dest/epoch_cache.d.ts
CHANGED
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
import { RollupContract } from '@aztec/ethereum';
|
|
2
|
+
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
4
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
4
5
|
import { type L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
5
6
|
import { type EpochCacheConfig } from './config.js';
|
|
6
7
|
export type EpochAndSlot = {
|
|
7
|
-
epoch:
|
|
8
|
-
slot:
|
|
8
|
+
epoch: EpochNumber;
|
|
9
|
+
slot: SlotNumber;
|
|
9
10
|
ts: bigint;
|
|
10
11
|
};
|
|
11
12
|
export type EpochCommitteeInfo = {
|
|
12
13
|
committee: EthAddress[] | undefined;
|
|
13
14
|
seed: bigint;
|
|
14
|
-
epoch:
|
|
15
|
+
epoch: EpochNumber;
|
|
15
16
|
};
|
|
16
|
-
export type SlotTag = 'now' | 'next' |
|
|
17
|
+
export type SlotTag = 'now' | 'next' | SlotNumber;
|
|
17
18
|
export interface EpochCacheInterface {
|
|
18
19
|
getCommittee(slot: SlotTag | undefined): Promise<EpochCommitteeInfo>;
|
|
19
20
|
getEpochAndSlotNow(): EpochAndSlot;
|
|
20
21
|
getEpochAndSlotInNextL1Slot(): EpochAndSlot & {
|
|
21
22
|
now: bigint;
|
|
22
23
|
};
|
|
23
|
-
getProposerIndexEncoding(epoch:
|
|
24
|
-
computeProposerIndex(slot:
|
|
24
|
+
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
|
|
25
|
+
computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
|
|
25
26
|
getProposerAttesterAddressInCurrentOrNextSlot(): Promise<{
|
|
26
27
|
currentProposer: EthAddress | undefined;
|
|
27
28
|
nextProposer: EthAddress | undefined;
|
|
28
|
-
currentSlot:
|
|
29
|
-
nextSlot:
|
|
29
|
+
currentSlot: SlotNumber;
|
|
30
|
+
nextSlot: SlotNumber;
|
|
30
31
|
}>;
|
|
31
32
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
32
33
|
isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
|
|
@@ -49,11 +50,14 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
49
50
|
cacheSize: number;
|
|
50
51
|
validatorRefreshIntervalSeconds: number;
|
|
51
52
|
};
|
|
52
|
-
protected cache: Map<
|
|
53
|
+
protected cache: Map<EpochNumber, EpochCommitteeInfo>;
|
|
53
54
|
private allValidators;
|
|
54
55
|
private lastValidatorRefresh;
|
|
55
56
|
private readonly log;
|
|
56
|
-
constructor(rollup: RollupContract, l1constants
|
|
57
|
+
constructor(rollup: RollupContract, l1constants: L1RollupConstants & {
|
|
58
|
+
lagInEpochsForValidatorSet: number;
|
|
59
|
+
lagInEpochsForRandao: number;
|
|
60
|
+
}, dateProvider?: DateProvider, config?: {
|
|
57
61
|
cacheSize: number;
|
|
58
62
|
validatorRefreshIntervalSeconds: number;
|
|
59
63
|
});
|
|
@@ -70,7 +74,7 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
70
74
|
now: bigint;
|
|
71
75
|
};
|
|
72
76
|
private getEpochAndSlotAtTimestamp;
|
|
73
|
-
getCommitteeForEpoch(epoch:
|
|
77
|
+
getCommitteeForEpoch(epoch: EpochNumber): Promise<EpochCommitteeInfo>;
|
|
74
78
|
/**
|
|
75
79
|
* Get the current validator set
|
|
76
80
|
* @param nextSlot - If true, get the validator set for the next slot.
|
|
@@ -82,8 +86,8 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
82
86
|
/**
|
|
83
87
|
* Get the ABI encoding of the proposer index - see ValidatorSelectionLib.sol computeProposerIndex
|
|
84
88
|
*/
|
|
85
|
-
getProposerIndexEncoding(epoch:
|
|
86
|
-
computeProposerIndex(slot:
|
|
89
|
+
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
|
|
90
|
+
computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
|
|
87
91
|
/**
|
|
88
92
|
* Returns the current and next proposer's attester address
|
|
89
93
|
*
|
|
@@ -91,8 +95,8 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
91
95
|
* which can be the next slot. If this is the case, then it will send proposals early.
|
|
92
96
|
*/
|
|
93
97
|
getProposerAttesterAddressInCurrentOrNextSlot(): Promise<{
|
|
94
|
-
currentSlot:
|
|
95
|
-
nextSlot:
|
|
98
|
+
currentSlot: SlotNumber;
|
|
99
|
+
nextSlot: SlotNumber;
|
|
96
100
|
currentProposer: EthAddress | undefined;
|
|
97
101
|
nextProposer: EthAddress | undefined;
|
|
98
102
|
}>;
|
|
@@ -101,25 +105,19 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
101
105
|
* @returns The proposer attester address. If the committee does not exist, we throw a NoCommitteeError.
|
|
102
106
|
* If the committee is empty (i.e. target committee size is 0, and anyone can propose), we return undefined.
|
|
103
107
|
*/
|
|
104
|
-
getProposerAttesterAddressInSlot(slot:
|
|
108
|
+
getProposerAttesterAddressInSlot(slot: SlotNumber): Promise<EthAddress | undefined>;
|
|
105
109
|
/**
|
|
106
110
|
* Get the proposer attester address in the next slot
|
|
107
111
|
* @returns The proposer attester address. If the committee does not exist, we throw a NoCommitteeError.
|
|
108
112
|
* If the committee is empty (i.e. target committee size is 0, and anyone can propose), we return undefined.
|
|
109
113
|
*/
|
|
110
114
|
getProposerAttesterAddressInNextSlot(): Promise<EthAddress | undefined>;
|
|
111
|
-
/**
|
|
112
|
-
* Get the proposer attester address at a given epoch and slot
|
|
113
|
-
* @param when - The epoch and slot to get the proposer attester address at
|
|
114
|
-
* @returns The proposer attester address. If the committee does not exist, we throw a NoCommitteeError.
|
|
115
|
-
* If the committee is empty (i.e. target committee size is 0, and anyone can propose), we return undefined.
|
|
116
|
-
*/
|
|
117
115
|
private getProposerAttesterAddressAt;
|
|
118
|
-
getProposerFromEpochCommittee(epochCommitteeInfo: EpochCommitteeInfo, slot:
|
|
116
|
+
getProposerFromEpochCommittee(epochCommitteeInfo: EpochCommitteeInfo, slot: SlotNumber): EthAddress | undefined;
|
|
119
117
|
/** Check if a validator is in the given slot's committee */
|
|
120
118
|
isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
|
|
121
119
|
/** From the set of given addresses, return all that are on the committee for the given slot */
|
|
122
120
|
filterInCommittee(slot: SlotTag, validators: EthAddress[]): Promise<EthAddress[]>;
|
|
123
121
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
124
122
|
}
|
|
125
|
-
//# sourceMappingURL=
|
|
123
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXBvY2hfY2FjaGUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9lcG9jaF9jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQW9CLGNBQWMsRUFBdUIsTUFBTSxpQkFBaUIsQ0FBQztBQUN4RixPQUFPLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUUzRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxFQUNMLEtBQUssaUJBQWlCLEVBT3ZCLE1BQU0sNkJBQTZCLENBQUM7QUFJckMsT0FBTyxFQUFFLEtBQUssZ0JBQWdCLEVBQThCLE1BQU0sYUFBYSxDQUFDO0FBRWhGLE1BQU0sTUFBTSxZQUFZLEdBQUc7SUFDekIsS0FBSyxFQUFFLFdBQVcsQ0FBQztJQUNuQixJQUFJLEVBQUUsVUFBVSxDQUFDO0lBQ2pCLEVBQUUsRUFBRSxNQUFNLENBQUM7Q0FDWixDQUFDO0FBRUYsTUFBTSxNQUFNLGtCQUFrQixHQUFHO0lBQy9CLFNBQVMsRUFBRSxVQUFVLEVBQUUsR0FBRyxTQUFTLENBQUM7SUFDcEMsSUFBSSxFQUFFLE1BQU0sQ0FBQztJQUNiLEtBQUssRUFBRSxXQUFXLENBQUM7Q0FDcEIsQ0FBQztBQUVGLE1BQU0sTUFBTSxPQUFPLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxVQUFVLENBQUM7QUFFbEQsTUFBTSxXQUFXLG1CQUFtQjtJQUNsQyxZQUFZLENBQUMsSUFBSSxFQUFFLE9BQU8sR0FBRyxTQUFTLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDckUsa0JBQWtCLElBQUksWUFBWSxDQUFDO0lBQ25DLDJCQUEyQixJQUFJLFlBQVksR0FBRztRQUFFLEdBQUcsRUFBRSxNQUFNLENBQUE7S0FBRSxDQUFDO0lBQzlELHdCQUF3QixDQUFD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
|
|
@@ -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,
|
|
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
|
@@ -2,7 +2,7 @@ import { NoCommitteeError, RollupContract, createEthereumChain } from '@aztec/et
|
|
|
2
2
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
5
|
-
import {
|
|
5
|
+
import { getEpochAtSlot, getEpochNumberAtTimestamp, getSlotAtTimestamp, getSlotRangeForEpoch, getTimestampForSlot, getTimestampRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
|
|
6
6
|
import { createPublicClient, encodeAbiParameters, fallback, http, keccak256 } from 'viem';
|
|
7
7
|
import { getEpochCacheConfigEnvVars } from './config.js';
|
|
8
8
|
/**
|
|
@@ -18,11 +18,12 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
18
18
|
l1constants;
|
|
19
19
|
dateProvider;
|
|
20
20
|
config;
|
|
21
|
+
// eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
|
|
21
22
|
cache;
|
|
22
23
|
allValidators;
|
|
23
24
|
lastValidatorRefresh;
|
|
24
25
|
log;
|
|
25
|
-
constructor(rollup, l1constants
|
|
26
|
+
constructor(rollup, l1constants, dateProvider = new DateProvider(), config = {
|
|
26
27
|
cacheSize: 12,
|
|
27
28
|
validatorRefreshIntervalSeconds: 60
|
|
28
29
|
}){
|
|
@@ -53,12 +54,14 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
53
54
|
});
|
|
54
55
|
rollup = new RollupContract(publicClient, rollupOrAddress.toString());
|
|
55
56
|
}
|
|
56
|
-
const [l1StartBlock, l1GenesisTime, proofSubmissionEpochs, slotDuration, epochDuration] = await Promise.all([
|
|
57
|
+
const [l1StartBlock, l1GenesisTime, proofSubmissionEpochs, slotDuration, epochDuration, lagInEpochsForValidatorSet, lagInEpochsForRandao] = await Promise.all([
|
|
57
58
|
rollup.getL1StartBlock(),
|
|
58
59
|
rollup.getL1GenesisTime(),
|
|
59
60
|
rollup.getProofSubmissionEpochs(),
|
|
60
61
|
rollup.getSlotDuration(),
|
|
61
|
-
rollup.getEpochDuration()
|
|
62
|
+
rollup.getEpochDuration(),
|
|
63
|
+
rollup.getLagInEpochsForValidatorSet(),
|
|
64
|
+
rollup.getLagInEpochsForRandao()
|
|
62
65
|
]);
|
|
63
66
|
const l1RollupConstants = {
|
|
64
67
|
l1StartBlock,
|
|
@@ -66,7 +69,9 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
66
69
|
proofSubmissionEpochs: Number(proofSubmissionEpochs),
|
|
67
70
|
slotDuration: Number(slotDuration),
|
|
68
71
|
epochDuration: Number(epochDuration),
|
|
69
|
-
ethereumSlotDuration: config.ethereumSlotDuration
|
|
72
|
+
ethereumSlotDuration: config.ethereumSlotDuration,
|
|
73
|
+
lagInEpochsForValidatorSet: Number(lagInEpochsForValidatorSet),
|
|
74
|
+
lagInEpochsForRandao: Number(lagInEpochsForRandao)
|
|
70
75
|
};
|
|
71
76
|
return new EpochCache(rollup, l1RollupConstants, deps.dateProvider);
|
|
72
77
|
}
|
|
@@ -145,10 +150,18 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
145
150
|
}
|
|
146
151
|
async computeCommittee(when) {
|
|
147
152
|
const { ts, epoch } = when;
|
|
148
|
-
const [committeeHex, seed] = await Promise.all([
|
|
153
|
+
const [committeeHex, seed, l1Timestamp] = await Promise.all([
|
|
149
154
|
this.rollup.getCommitteeAt(ts),
|
|
150
|
-
this.rollup.getSampleSeedAt(ts)
|
|
155
|
+
this.rollup.getSampleSeedAt(ts),
|
|
156
|
+
this.rollup.client.getBlock({
|
|
157
|
+
includeTransactions: false
|
|
158
|
+
}).then((b)=>b.timestamp)
|
|
151
159
|
]);
|
|
160
|
+
const { lagInEpochsForValidatorSet, epochDuration, slotDuration } = this.l1constants;
|
|
161
|
+
const sub = BigInt(lagInEpochsForValidatorSet) * BigInt(epochDuration) * BigInt(slotDuration);
|
|
162
|
+
if (ts - sub > l1Timestamp) {
|
|
163
|
+
throw new Error(`Cannot query committee for future epoch ${epoch} with timestamp ${ts} (current L1 time is ${l1Timestamp}). Check your Ethereum node is synced.`);
|
|
164
|
+
}
|
|
152
165
|
const committee = committeeHex?.map((v)=>EthAddress.fromString(v));
|
|
153
166
|
return {
|
|
154
167
|
committee,
|
|
@@ -173,8 +186,8 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
173
186
|
name: 'seed'
|
|
174
187
|
}
|
|
175
188
|
], [
|
|
176
|
-
epoch,
|
|
177
|
-
slot,
|
|
189
|
+
BigInt(epoch),
|
|
190
|
+
BigInt(slot),
|
|
178
191
|
seed
|
|
179
192
|
]);
|
|
180
193
|
}
|
package/dest/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './epoch_cache.js';
|
|
2
2
|
export * from './config.js';
|
|
3
|
-
//# sourceMappingURL=
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsYUFBYSxDQUFDIn0=
|
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.fce3e4f",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
"tsconfig": "./tsconfig.json"
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
|
-
"build": "yarn clean &&
|
|
19
|
-
"build:dev": "
|
|
18
|
+
"build": "yarn clean && tsgo -b",
|
|
19
|
+
"build:dev": "tsgo -b --watch",
|
|
20
20
|
"clean": "rm -rf ./dest .tsbuildinfo",
|
|
21
|
-
"start:dev": "
|
|
21
|
+
"start:dev": "concurrently -k \"tsgo -b -w\" \"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,22 +26,23 @@
|
|
|
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.fce3e4f",
|
|
30
|
+
"@aztec/foundation": "0.0.1-commit.fce3e4f",
|
|
31
|
+
"@aztec/l1-artifacts": "0.0.1-commit.fce3e4f",
|
|
32
|
+
"@aztec/stdlib": "0.0.1-commit.fce3e4f",
|
|
33
33
|
"@viem/anvil": "^0.0.10",
|
|
34
34
|
"dotenv": "^16.0.3",
|
|
35
35
|
"get-port": "^7.1.0",
|
|
36
36
|
"jest-mock-extended": "^4.0.0",
|
|
37
37
|
"tslib": "^2.4.0",
|
|
38
|
-
"viem": "npm:@
|
|
38
|
+
"viem": "npm:@aztec/viem@2.38.2",
|
|
39
39
|
"zod": "^3.23.8"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
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.20251126.1",
|
|
45
46
|
"jest": "^30.0.0",
|
|
46
47
|
"ts-node": "^10.9.1",
|
|
47
48
|
"typescript": "^5.3.3"
|
package/src/epoch_cache.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { NoCommitteeError, RollupContract, createEthereumChain } from '@aztec/ethereum';
|
|
2
|
+
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
4
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
4
5
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
5
6
|
import {
|
|
6
|
-
EmptyL1RollupConstants,
|
|
7
7
|
type L1RollupConstants,
|
|
8
8
|
getEpochAtSlot,
|
|
9
9
|
getEpochNumberAtTimestamp,
|
|
@@ -18,30 +18,30 @@ import { createPublicClient, encodeAbiParameters, fallback, http, keccak256 } fr
|
|
|
18
18
|
import { type EpochCacheConfig, getEpochCacheConfigEnvVars } from './config.js';
|
|
19
19
|
|
|
20
20
|
export type EpochAndSlot = {
|
|
21
|
-
epoch:
|
|
22
|
-
slot:
|
|
21
|
+
epoch: EpochNumber;
|
|
22
|
+
slot: SlotNumber;
|
|
23
23
|
ts: bigint;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
export type EpochCommitteeInfo = {
|
|
27
27
|
committee: EthAddress[] | undefined;
|
|
28
28
|
seed: bigint;
|
|
29
|
-
epoch:
|
|
29
|
+
epoch: EpochNumber;
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
-
export type SlotTag = 'now' | 'next' |
|
|
32
|
+
export type SlotTag = 'now' | 'next' | SlotNumber;
|
|
33
33
|
|
|
34
34
|
export interface EpochCacheInterface {
|
|
35
35
|
getCommittee(slot: SlotTag | undefined): Promise<EpochCommitteeInfo>;
|
|
36
36
|
getEpochAndSlotNow(): EpochAndSlot;
|
|
37
37
|
getEpochAndSlotInNextL1Slot(): EpochAndSlot & { now: bigint };
|
|
38
|
-
getProposerIndexEncoding(epoch:
|
|
39
|
-
computeProposerIndex(slot:
|
|
38
|
+
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
|
|
39
|
+
computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
|
|
40
40
|
getProposerAttesterAddressInCurrentOrNextSlot(): Promise<{
|
|
41
41
|
currentProposer: EthAddress | undefined;
|
|
42
42
|
nextProposer: EthAddress | undefined;
|
|
43
|
-
currentSlot:
|
|
44
|
-
nextSlot:
|
|
43
|
+
currentSlot: SlotNumber;
|
|
44
|
+
nextSlot: SlotNumber;
|
|
45
45
|
}>;
|
|
46
46
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
47
47
|
isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
|
|
@@ -58,14 +58,18 @@ export interface EpochCacheInterface {
|
|
|
58
58
|
* Note: This class is very dependent on the system clock being in sync.
|
|
59
59
|
*/
|
|
60
60
|
export class EpochCache implements EpochCacheInterface {
|
|
61
|
-
|
|
61
|
+
// eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
|
|
62
|
+
protected cache: Map<EpochNumber, EpochCommitteeInfo> = new Map();
|
|
62
63
|
private allValidators: Set<string> = new Set();
|
|
63
64
|
private lastValidatorRefresh = 0;
|
|
64
65
|
private readonly log: Logger = createLogger('epoch-cache');
|
|
65
66
|
|
|
66
67
|
constructor(
|
|
67
68
|
private rollup: RollupContract,
|
|
68
|
-
private readonly l1constants: L1RollupConstants
|
|
69
|
+
private readonly l1constants: L1RollupConstants & {
|
|
70
|
+
lagInEpochsForValidatorSet: number;
|
|
71
|
+
lagInEpochsForRandao: number;
|
|
72
|
+
},
|
|
69
73
|
private readonly dateProvider: DateProvider = new DateProvider(),
|
|
70
74
|
protected readonly config = { cacheSize: 12, validatorRefreshIntervalSeconds: 60 },
|
|
71
75
|
) {
|
|
@@ -95,21 +99,33 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
95
99
|
rollup = new RollupContract(publicClient, rollupOrAddress.toString());
|
|
96
100
|
}
|
|
97
101
|
|
|
98
|
-
const [
|
|
102
|
+
const [
|
|
103
|
+
l1StartBlock,
|
|
104
|
+
l1GenesisTime,
|
|
105
|
+
proofSubmissionEpochs,
|
|
106
|
+
slotDuration,
|
|
107
|
+
epochDuration,
|
|
108
|
+
lagInEpochsForValidatorSet,
|
|
109
|
+
lagInEpochsForRandao,
|
|
110
|
+
] = await Promise.all([
|
|
99
111
|
rollup.getL1StartBlock(),
|
|
100
112
|
rollup.getL1GenesisTime(),
|
|
101
113
|
rollup.getProofSubmissionEpochs(),
|
|
102
114
|
rollup.getSlotDuration(),
|
|
103
115
|
rollup.getEpochDuration(),
|
|
116
|
+
rollup.getLagInEpochsForValidatorSet(),
|
|
117
|
+
rollup.getLagInEpochsForRandao(),
|
|
104
118
|
] as const);
|
|
105
119
|
|
|
106
|
-
const l1RollupConstants
|
|
120
|
+
const l1RollupConstants = {
|
|
107
121
|
l1StartBlock,
|
|
108
122
|
l1GenesisTime,
|
|
109
123
|
proofSubmissionEpochs: Number(proofSubmissionEpochs),
|
|
110
124
|
slotDuration: Number(slotDuration),
|
|
111
125
|
epochDuration: Number(epochDuration),
|
|
112
126
|
ethereumSlotDuration: config.ethereumSlotDuration,
|
|
127
|
+
lagInEpochsForValidatorSet: Number(lagInEpochsForValidatorSet),
|
|
128
|
+
lagInEpochsForRandao: Number(lagInEpochsForRandao),
|
|
113
129
|
};
|
|
114
130
|
|
|
115
131
|
return new EpochCache(rollup, l1RollupConstants, deps.dateProvider);
|
|
@@ -128,7 +144,7 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
128
144
|
return BigInt(Math.floor(this.dateProvider.now() / 1000));
|
|
129
145
|
}
|
|
130
146
|
|
|
131
|
-
private getEpochAndSlotAtSlot(slot:
|
|
147
|
+
private getEpochAndSlotAtSlot(slot: SlotNumber): EpochAndSlot {
|
|
132
148
|
const epoch = getEpochAtSlot(slot, this.l1constants);
|
|
133
149
|
const ts = getTimestampRangeForEpoch(epoch, this.l1constants)[0];
|
|
134
150
|
return { epoch, ts, slot };
|
|
@@ -149,7 +165,7 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
149
165
|
};
|
|
150
166
|
}
|
|
151
167
|
|
|
152
|
-
public getCommitteeForEpoch(epoch:
|
|
168
|
+
public getCommitteeForEpoch(epoch: EpochNumber): Promise<EpochCommitteeInfo> {
|
|
153
169
|
const [startSlot] = getSlotRangeForEpoch(epoch, this.l1constants);
|
|
154
170
|
return this.getCommittee(startSlot);
|
|
155
171
|
}
|
|
@@ -191,9 +207,20 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
191
207
|
}
|
|
192
208
|
}
|
|
193
209
|
|
|
194
|
-
private async computeCommittee(when: { epoch:
|
|
210
|
+
private async computeCommittee(when: { epoch: EpochNumber; ts: bigint }): Promise<EpochCommitteeInfo> {
|
|
195
211
|
const { ts, epoch } = when;
|
|
196
|
-
const [committeeHex, seed] = await Promise.all([
|
|
212
|
+
const [committeeHex, seed, l1Timestamp] = await Promise.all([
|
|
213
|
+
this.rollup.getCommitteeAt(ts),
|
|
214
|
+
this.rollup.getSampleSeedAt(ts),
|
|
215
|
+
this.rollup.client.getBlock({ includeTransactions: false }).then(b => b.timestamp),
|
|
216
|
+
]);
|
|
217
|
+
const { lagInEpochsForValidatorSet, epochDuration, slotDuration } = this.l1constants;
|
|
218
|
+
const sub = BigInt(lagInEpochsForValidatorSet) * BigInt(epochDuration) * BigInt(slotDuration);
|
|
219
|
+
if (ts - sub > l1Timestamp) {
|
|
220
|
+
throw new Error(
|
|
221
|
+
`Cannot query committee for future epoch ${epoch} with timestamp ${ts} (current L1 time is ${l1Timestamp}). Check your Ethereum node is synced.`,
|
|
222
|
+
);
|
|
223
|
+
}
|
|
197
224
|
const committee = committeeHex?.map((v: `0x${string}`) => EthAddress.fromString(v));
|
|
198
225
|
return { committee, seed, epoch };
|
|
199
226
|
}
|
|
@@ -201,18 +228,18 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
201
228
|
/**
|
|
202
229
|
* Get the ABI encoding of the proposer index - see ValidatorSelectionLib.sol computeProposerIndex
|
|
203
230
|
*/
|
|
204
|
-
getProposerIndexEncoding(epoch:
|
|
231
|
+
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}` {
|
|
205
232
|
return encodeAbiParameters(
|
|
206
233
|
[
|
|
207
234
|
{ type: 'uint256', name: 'epoch' },
|
|
208
235
|
{ type: 'uint256', name: 'slot' },
|
|
209
236
|
{ type: 'uint256', name: 'seed' },
|
|
210
237
|
],
|
|
211
|
-
[epoch, slot, seed],
|
|
238
|
+
[BigInt(epoch), BigInt(slot), seed],
|
|
212
239
|
);
|
|
213
240
|
}
|
|
214
241
|
|
|
215
|
-
public computeProposerIndex(slot:
|
|
242
|
+
public computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint {
|
|
216
243
|
// if committe size is 0, then mod 1 is 0
|
|
217
244
|
if (size === 0n) {
|
|
218
245
|
return 0n;
|
|
@@ -227,8 +254,8 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
227
254
|
* which can be the next slot. If this is the case, then it will send proposals early.
|
|
228
255
|
*/
|
|
229
256
|
public async getProposerAttesterAddressInCurrentOrNextSlot(): Promise<{
|
|
230
|
-
currentSlot:
|
|
231
|
-
nextSlot:
|
|
257
|
+
currentSlot: SlotNumber;
|
|
258
|
+
nextSlot: SlotNumber;
|
|
232
259
|
currentProposer: EthAddress | undefined;
|
|
233
260
|
nextProposer: EthAddress | undefined;
|
|
234
261
|
}> {
|
|
@@ -248,7 +275,7 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
248
275
|
* @returns The proposer attester address. If the committee does not exist, we throw a NoCommitteeError.
|
|
249
276
|
* If the committee is empty (i.e. target committee size is 0, and anyone can propose), we return undefined.
|
|
250
277
|
*/
|
|
251
|
-
public getProposerAttesterAddressInSlot(slot:
|
|
278
|
+
public getProposerAttesterAddressInSlot(slot: SlotNumber): Promise<EthAddress | undefined> {
|
|
252
279
|
const epochAndSlot = this.getEpochAndSlotAtSlot(slot);
|
|
253
280
|
return this.getProposerAttesterAddressAt(epochAndSlot);
|
|
254
281
|
}
|
|
@@ -282,7 +309,10 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
282
309
|
return committee[Number(proposerIndex)];
|
|
283
310
|
}
|
|
284
311
|
|
|
285
|
-
public getProposerFromEpochCommittee(
|
|
312
|
+
public getProposerFromEpochCommittee(
|
|
313
|
+
epochCommitteeInfo: EpochCommitteeInfo,
|
|
314
|
+
slot: SlotNumber,
|
|
315
|
+
): EthAddress | undefined {
|
|
286
316
|
if (!epochCommitteeInfo.committee || epochCommitteeInfo.committee.length === 0) {
|
|
287
317
|
return undefined;
|
|
288
318
|
}
|