@aztec/epoch-cache 0.0.1-commit.d3ec352c → 0.0.1-commit.d431d1c
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 +3 -2
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +2 -1
- package/dest/epoch_cache.d.ts +24 -16
- package/dest/epoch_cache.d.ts.map +1 -1
- package/dest/epoch_cache.js +36 -17
- package/package.json +7 -7
- package/src/config.ts +2 -6
- package/src/epoch_cache.ts +46 -27
package/dest/config.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type L1ContractsConfig
|
|
1
|
+
import { type L1ContractsConfig } from '@aztec/ethereum/config';
|
|
2
|
+
import { type L1ReaderConfig } from '@aztec/ethereum/l1-reader';
|
|
2
3
|
export type EpochCacheConfig = Pick<L1ReaderConfig & L1ContractsConfig, 'l1RpcUrls' | 'l1ChainId' | 'viemPollingIntervalMS' | 'ethereumSlotDuration'>;
|
|
3
4
|
export declare function getEpochCacheConfigEnvVars(): EpochCacheConfig;
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLGlCQUFpQixFQUErQixNQUFNLHdCQUF3QixDQUFDO0FBQzdGLE9BQU8sRUFBRSxLQUFLLGNBQWMsRUFBNEIsTUFBTSwyQkFBMkIsQ0FBQztBQUUxRixNQUFNLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUNqQyxjQUFjLEdBQUcsaUJBQWlCLEVBQ2xDLFdBQVcsR0FBRyxXQUFXLEdBQUcsdUJBQXVCLEdBQUcsc0JBQXNCLENBQzdFLENBQUM7QUFFRix3QkFBZ0IsMEJBQTBCLElBQUksZ0JBQWdCLENBRTdEIn0=
|
package/dest/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAA+B,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,KAAK,cAAc,EAA4B,MAAM,2BAA2B,CAAC;AAE1F,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,cAAc,GAAG,iBAAiB,EAClC,WAAW,GAAG,WAAW,GAAG,uBAAuB,GAAG,sBAAsB,CAC7E,CAAC;AAEF,wBAAgB,0BAA0B,IAAI,gBAAgB,CAE7D"}
|
package/dest/config.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { getL1ContractsConfigEnvVars
|
|
1
|
+
import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config';
|
|
2
|
+
import { getL1ReaderConfigFromEnv } from '@aztec/ethereum/l1-reader';
|
|
2
3
|
export function getEpochCacheConfigEnvVars() {
|
|
3
4
|
return {
|
|
4
5
|
...getL1ReaderConfigFromEnv(),
|
package/dest/epoch_cache.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RollupContract } from '@aztec/ethereum';
|
|
1
|
+
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
2
2
|
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
4
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
@@ -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,11 @@ 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
|
+
getProposerAttesterAddressInSlot(slot: SlotNumber): Promise<EthAddress | undefined>;
|
|
32
33
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
33
34
|
isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
|
|
34
35
|
filterInCommittee(slot: SlotTag, validators: EthAddress[]): Promise<EthAddress[]>;
|
|
@@ -75,6 +76,20 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
75
76
|
};
|
|
76
77
|
private getEpochAndSlotAtTimestamp;
|
|
77
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>;
|
|
78
93
|
/**
|
|
79
94
|
* Get the current validator set
|
|
80
95
|
* @param nextSlot - If true, get the validator set for the next slot.
|
|
@@ -88,18 +103,11 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
88
103
|
*/
|
|
89
104
|
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
|
|
90
105
|
computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
|
|
91
|
-
/**
|
|
92
|
-
|
|
93
|
-
*
|
|
94
|
-
* We return the next proposer's attester address as the node will check if it is the proposer at the next ethereum block,
|
|
95
|
-
* which can be the next slot. If this is the case, then it will send proposals early.
|
|
96
|
-
*/
|
|
97
|
-
getProposerAttesterAddressInCurrentOrNextSlot(): Promise<{
|
|
106
|
+
/** Returns the current and next L2 slot numbers. */
|
|
107
|
+
getCurrentAndNextSlot(): {
|
|
98
108
|
currentSlot: SlotNumber;
|
|
99
109
|
nextSlot: SlotNumber;
|
|
100
|
-
|
|
101
|
-
nextProposer: EthAddress | undefined;
|
|
102
|
-
}>;
|
|
110
|
+
};
|
|
103
111
|
/**
|
|
104
112
|
* Get the proposer attester address in the given L2 slot
|
|
105
113
|
* @returns The proposer attester address. If the committee does not exist, we throw a NoCommitteeError.
|
|
@@ -120,4 +128,4 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
120
128
|
filterInCommittee(slot: SlotTag, validators: EthAddress[]): Promise<EthAddress[]>;
|
|
121
129
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
122
130
|
}
|
|
123
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
131
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXBvY2hfY2FjaGUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9lcG9jaF9jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQW9CLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDMUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEVBQ0wsS0FBSyxpQkFBaUIsRUFPdkIsTUFBTSw2QkFBNkIsQ0FBQztBQUlyQyxPQUFPLEVBQUUsS0FBSyxnQkFBZ0IsRUFBOEIsTUFBTSxhQUFhLENBQUM7QUFFaEYsTUFBTSxNQUFNLFlBQVksR0FBRztJQUN6QixLQUFLLEVBQUUsV0FBVyxDQUFDO0lBQ25CLElBQUksRUFBRSxVQUFVLENBQUM7SUFDakIsRUFBRSxFQUFFLE1BQU0sQ0FBQztDQUNaLENBQUM7QUFFRixNQUFNLE1BQU0sa0JBQWtCLEdBQUc7SUFDL0IsU0FBUyxFQUFFLFVBQVUsRUFBRSxHQUFHLFNBQVMsQ0FBQztJQUNwQyxJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ2IsS0FBSyxFQUFFLFdBQVcsQ0FBQztJQUNuQiwrREFBK0Q7SUFDL0QsaUJBQWlCLEVBQUUsT0FBTyxDQUFDO0NBQzVCLENBQUM7QUFFRixNQUFNLE1BQU0sT0FBTyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsVUFBVSxDQUFDO0FBRWxELE1BQU0sV0FBVyxtQkFBbUI7SUFDbEMsWUFBWSxDQUFDLElBQUksRUFBRSxPQUFPLEdBQUcsU0FBUyxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JFLGtCQUFrQixJQUFJLFlBQVksQ0FBQztJQUNuQywyQkFBMkIsSUFBSSxZQUFZLEdBQUc7UUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFBO0tBQUUsQ0FBQztJQUM5RCx3QkFBd0IsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLE1BQU0sR0FBRyxLQUFLLE1BQU0sRUFBRSxDQUFDO0lBQzVGLG9CQUFvQixDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLEdBQUcsTUFBTSxDQUFDO0lBQy9GLHFCQUFxQixJQUFJO1FBQUUsV0FBVyxFQUFFLFVBQVUsQ0FBQztRQUFDLFFBQVEsRUFBRSxVQUFVLENBQUE7S0FBRSxDQUFDO0lBQzNFLGdDQUFnQyxDQUFDLElBQUksRUFBRSxVQUFVLEdBQUcsT0FBTyxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsQ0FBQztJQUNwRix1QkFBdUIsSUFBSSxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztJQUNqRCxhQUFhLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN0RSxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsR0FBRyxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztDQUNuRjtBQUVEOzs7Ozs7OztHQVFHO0FBQ0gscUJBQWEsVUFBVyxZQUFXLG1CQUFtQjtJQVFsRCxPQUFPLENBQUMsTUFBTTtJQUNkLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVztJQUk1QixPQUFPLENBQUMsUUFBUSxDQUFDLFlBQVk7SUFDN0IsU0FBUyxDQUFDLFFBQVEsQ0FBQyxNQUFNOzs7O0lBWjNCLFNBQVMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLFdBQVcsRUFBRSxrQkFBa0IsQ0FBQyxDQUFhO0lBQ2xFLE9BQU8sQ0FBQyxhQUFhLENBQTBCO0lBQy9DLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBSztJQUNqQyxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBdUM7SUFFM0QsWUFDVSxNQUFNLEVBQUUsY0FBYyxFQUNiLFdBQVcsRUFBRSxpQkFBaUIsR0FBRztRQUNoRCwwQkFBMEIsRUFBRSxNQUFNLENBQUM7UUFDbkMsb0JBQW9CLEVBQUUsTUFBTSxDQUFDO0tBQzlCLEVBQ2dCLFlBQVksR0FBRSxZQUFpQyxFQUM3QyxNQUFNOzs7S0FBeUQsRUFLbkY7SUFFRCxPQUFhLE1BQU0sQ0FDakIsZUFBZSxFQUFFLFVBQVUsR0FBRyxjQUFjLEVBQzVDLE1BQU0sQ0FBQyxFQUFFLGdCQUFnQixFQUN6QixJQUFJLEdBQUU7UUFBRSxZQUFZLENBQUMsRUFBRSxZQUFZLENBQUE7S0FBTyx1QkFnRDNDO0lBRU0sY0FBYyxJQUFJLGlCQUFpQixDQUV6QztJQUVNLGtCQUFrQixJQUFJLFlBQVksR0FBRztRQUFFLEdBQUcsRUFBRSxNQUFNLENBQUE7S0FBRSxDQUcxRDtJQUVNLFlBQVksSUFBSSxNQUFNLENBRTVCO0lBRUQsT0FBTyxDQUFDLHFCQUFxQjtJQU10QiwyQkFBMkIsSUFBSSxZQUFZLEdBQUc7UUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFBO0tBQUUsQ0FJbkU7SUFFRCxPQUFPLENBQUMsMEJBQTBCO0lBUzNCLG9CQUFvQixDQUFDLEtBQUssRUFBRSxXQUFXLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBRzNFO0lBRUQ7Ozs7O09BS0c7SUFDVSxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsV0FBVyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FPbkU7SUFFRDs7Ozs7T0FLRztJQUNVLHVCQUF1QixDQUFDLElBQUksR0FBRSxPQUFlLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQVM1RTtJQUVEOzs7O09BSUc7SUFDVSxZQUFZLENBQUMsSUFBSSxHQUFFLE9BQWUsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FvQjVFO0lBRUQsT0FBTyxDQUFDLG9CQUFvQjtZQVVkLGdCQUFnQjtJQWtCOUI7O09BRUc7SUFDSCx3QkFBd0IsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLE1BQU0sR0FBRyxLQUFLLE1BQU0sRUFBRSxDQVMxRjtJQUVNLG9CQUFvQixDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLEdBQUcsTUFBTSxDQU1wRztJQUVELG9EQUFvRDtJQUM3QyxxQkFBcUIsSUFBSTtRQUFFLFdBQVcsRUFBRSxVQUFVLENBQUM7UUFBQyxRQUFRLEVBQUUsVUFBVSxDQUFBO0tBQUUsQ0FRaEY7SUFFRDs7OztPQUlHO0lBQ0ksZ0NBQWdDLENBQUMsSUFBSSxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxDQUd6RjtJQUVEOzs7O09BSUc7SUFDSSxvQ0FBb0MsSUFBSSxPQUFPLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxDQUc3RTtZQVFhLDRCQUE0QjtJQWFuQyw2QkFBNkIsQ0FDbEMsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQ3RDLElBQUksRUFBRSxVQUFVLEdBQ2YsVUFBVSxHQUFHLFNBQVMsQ0FZeEI7SUFFRCw0REFBNEQ7SUFDdEQsYUFBYSxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBTTFFO0lBRUQsK0ZBQStGO0lBQ3pGLGlCQUFpQixDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQU90RjtJQUVLLHVCQUF1QixJQUFJLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQVNyRDtDQUNGIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epoch_cache.d.ts","sourceRoot":"","sources":["../src/epoch_cache.ts"],"names":[],"mappings":"
|
|
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
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
2
|
+
import { NoCommitteeError, RollupContract } from '@aztec/ethereum/contracts';
|
|
2
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
5
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
@@ -49,7 +50,9 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
49
50
|
const chain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
|
|
50
51
|
const publicClient = createPublicClient({
|
|
51
52
|
chain: chain.chainInfo,
|
|
52
|
-
transport: fallback(config.l1RpcUrls.map((url)=>http(url
|
|
53
|
+
transport: fallback(config.l1RpcUrls.map((url)=>http(url, {
|
|
54
|
+
batch: false
|
|
55
|
+
}))),
|
|
53
56
|
pollingInterval: config.viemPollingIntervalMS
|
|
54
57
|
});
|
|
55
58
|
rollup = new RollupContract(publicClient, rollupOrAddress.toString());
|
|
@@ -118,6 +121,28 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
118
121
|
return this.getCommittee(startSlot);
|
|
119
122
|
}
|
|
120
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
|
+
/**
|
|
121
146
|
* Get the current validator set
|
|
122
147
|
* @param nextSlot - If true, get the validator set for the next slot.
|
|
123
148
|
* @returns The current validator set.
|
|
@@ -150,23 +175,24 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
150
175
|
}
|
|
151
176
|
async computeCommittee(when) {
|
|
152
177
|
const { ts, epoch } = when;
|
|
153
|
-
const [
|
|
178
|
+
const [committee, seedBuffer, l1Timestamp, isEscapeHatchOpen] = await Promise.all([
|
|
154
179
|
this.rollup.getCommitteeAt(ts),
|
|
155
180
|
this.rollup.getSampleSeedAt(ts),
|
|
156
181
|
this.rollup.client.getBlock({
|
|
157
182
|
includeTransactions: false
|
|
158
|
-
}).then((b)=>b.timestamp)
|
|
183
|
+
}).then((b)=>b.timestamp),
|
|
184
|
+
this.rollup.isEscapeHatchOpen(epoch)
|
|
159
185
|
]);
|
|
160
186
|
const { lagInEpochsForValidatorSet, epochDuration, slotDuration } = this.l1constants;
|
|
161
187
|
const sub = BigInt(lagInEpochsForValidatorSet) * BigInt(epochDuration) * BigInt(slotDuration);
|
|
162
188
|
if (ts - sub > l1Timestamp) {
|
|
163
189
|
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
190
|
}
|
|
165
|
-
const committee = committeeHex?.map((v)=>EthAddress.fromString(v));
|
|
166
191
|
return {
|
|
167
192
|
committee,
|
|
168
|
-
seed,
|
|
169
|
-
epoch
|
|
193
|
+
seed: seedBuffer.toBigInt(),
|
|
194
|
+
epoch,
|
|
195
|
+
isEscapeHatchOpen
|
|
170
196
|
};
|
|
171
197
|
}
|
|
172
198
|
/**
|
|
@@ -198,17 +224,10 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
198
224
|
}
|
|
199
225
|
return BigInt(keccak256(this.getProposerIndexEncoding(epoch, slot, seed))) % size;
|
|
200
226
|
}
|
|
201
|
-
/**
|
|
202
|
-
* Returns the current and next proposer's attester address
|
|
203
|
-
*
|
|
204
|
-
* We return the next proposer's attester address as the node will check if it is the proposer at the next ethereum block,
|
|
205
|
-
* which can be the next slot. If this is the case, then it will send proposals early.
|
|
206
|
-
*/ async getProposerAttesterAddressInCurrentOrNextSlot() {
|
|
227
|
+
/** Returns the current and next L2 slot numbers. */ getCurrentAndNextSlot() {
|
|
207
228
|
const current = this.getEpochAndSlotNow();
|
|
208
229
|
const next = this.getEpochAndSlotInNextL1Slot();
|
|
209
230
|
return {
|
|
210
|
-
currentProposer: await this.getProposerAttesterAddressAt(current),
|
|
211
|
-
nextProposer: await this.getProposerAttesterAddressAt(next),
|
|
212
231
|
currentSlot: current.slot,
|
|
213
232
|
nextSlot: next.slot
|
|
214
233
|
};
|
|
@@ -272,9 +291,9 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
272
291
|
const validatorRefreshTime = this.lastValidatorRefresh + validatorRefreshIntervalMs;
|
|
273
292
|
if (validatorRefreshTime < this.dateProvider.now()) {
|
|
274
293
|
const currentSet = await this.rollup.getAttesters();
|
|
275
|
-
this.allValidators = new Set(currentSet);
|
|
294
|
+
this.allValidators = new Set(currentSet.map((v)=>v.toString()));
|
|
276
295
|
this.lastValidatorRefresh = this.dateProvider.now();
|
|
277
296
|
}
|
|
278
|
-
return Array.from(this.allValidators.keys().map((v)=>EthAddress.fromString(v))
|
|
297
|
+
return Array.from(this.allValidators.keys()).map((v)=>EthAddress.fromString(v));
|
|
279
298
|
}
|
|
280
299
|
}
|
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.d431d1c",
|
|
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.d431d1c",
|
|
30
|
+
"@aztec/foundation": "0.0.1-commit.d431d1c",
|
|
31
|
+
"@aztec/l1-artifacts": "0.0.1-commit.d431d1c",
|
|
32
|
+
"@aztec/stdlib": "0.0.1-commit.d431d1c",
|
|
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/config.ts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
type L1ReaderConfig,
|
|
4
|
-
getL1ContractsConfigEnvVars,
|
|
5
|
-
getL1ReaderConfigFromEnv,
|
|
6
|
-
} from '@aztec/ethereum';
|
|
1
|
+
import { type L1ContractsConfig, getL1ContractsConfigEnvVars } from '@aztec/ethereum/config';
|
|
2
|
+
import { type L1ReaderConfig, getL1ReaderConfigFromEnv } from '@aztec/ethereum/l1-reader';
|
|
7
3
|
|
|
8
4
|
export type EpochCacheConfig = Pick<
|
|
9
5
|
L1ReaderConfig & L1ContractsConfig,
|
package/src/epoch_cache.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
2
|
+
import { NoCommitteeError, RollupContract } from '@aztec/ethereum/contracts';
|
|
2
3
|
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
5
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
@@ -27,6 +28,8 @@ export type EpochCommitteeInfo = {
|
|
|
27
28
|
committee: EthAddress[] | undefined;
|
|
28
29
|
seed: bigint;
|
|
29
30
|
epoch: EpochNumber;
|
|
31
|
+
/** True if the epoch is within an open escape hatch window. */
|
|
32
|
+
isEscapeHatchOpen: boolean;
|
|
30
33
|
};
|
|
31
34
|
|
|
32
35
|
export type SlotTag = 'now' | 'next' | SlotNumber;
|
|
@@ -37,12 +40,8 @@ export interface EpochCacheInterface {
|
|
|
37
40
|
getEpochAndSlotInNextL1Slot(): EpochAndSlot & { now: bigint };
|
|
38
41
|
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
|
|
39
42
|
computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
nextProposer: EthAddress | undefined;
|
|
43
|
-
currentSlot: SlotNumber;
|
|
44
|
-
nextSlot: SlotNumber;
|
|
45
|
-
}>;
|
|
43
|
+
getCurrentAndNextSlot(): { currentSlot: SlotNumber; nextSlot: SlotNumber };
|
|
44
|
+
getProposerAttesterAddressInSlot(slot: SlotNumber): Promise<EthAddress | undefined>;
|
|
46
45
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
47
46
|
isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
|
|
48
47
|
filterInCommittee(slot: SlotTag, validators: EthAddress[]): Promise<EthAddress[]>;
|
|
@@ -93,7 +92,7 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
93
92
|
const chain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
|
|
94
93
|
const publicClient = createPublicClient({
|
|
95
94
|
chain: chain.chainInfo,
|
|
96
|
-
transport: fallback(config.l1RpcUrls.map(url => http(url))),
|
|
95
|
+
transport: fallback(config.l1RpcUrls.map(url => http(url, { batch: false }))),
|
|
97
96
|
pollingInterval: config.viemPollingIntervalMS,
|
|
98
97
|
});
|
|
99
98
|
rollup = new RollupContract(publicClient, rollupOrAddress.toString());
|
|
@@ -170,6 +169,38 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
170
169
|
return this.getCommittee(startSlot);
|
|
171
170
|
}
|
|
172
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
|
+
|
|
173
204
|
/**
|
|
174
205
|
* Get the current validator set
|
|
175
206
|
* @param nextSlot - If true, get the validator set for the next slot.
|
|
@@ -209,10 +240,11 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
209
240
|
|
|
210
241
|
private async computeCommittee(when: { epoch: EpochNumber; ts: bigint }): Promise<EpochCommitteeInfo> {
|
|
211
242
|
const { ts, epoch } = when;
|
|
212
|
-
const [
|
|
243
|
+
const [committee, seedBuffer, l1Timestamp, isEscapeHatchOpen] = await Promise.all([
|
|
213
244
|
this.rollup.getCommitteeAt(ts),
|
|
214
245
|
this.rollup.getSampleSeedAt(ts),
|
|
215
246
|
this.rollup.client.getBlock({ includeTransactions: false }).then(b => b.timestamp),
|
|
247
|
+
this.rollup.isEscapeHatchOpen(epoch),
|
|
216
248
|
]);
|
|
217
249
|
const { lagInEpochsForValidatorSet, epochDuration, slotDuration } = this.l1constants;
|
|
218
250
|
const sub = BigInt(lagInEpochsForValidatorSet) * BigInt(epochDuration) * BigInt(slotDuration);
|
|
@@ -221,8 +253,7 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
221
253
|
`Cannot query committee for future epoch ${epoch} with timestamp ${ts} (current L1 time is ${l1Timestamp}). Check your Ethereum node is synced.`,
|
|
222
254
|
);
|
|
223
255
|
}
|
|
224
|
-
|
|
225
|
-
return { committee, seed, epoch };
|
|
256
|
+
return { committee, seed: seedBuffer.toBigInt(), epoch, isEscapeHatchOpen };
|
|
226
257
|
}
|
|
227
258
|
|
|
228
259
|
/**
|
|
@@ -247,24 +278,12 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
247
278
|
return BigInt(keccak256(this.getProposerIndexEncoding(epoch, slot, seed))) % size;
|
|
248
279
|
}
|
|
249
280
|
|
|
250
|
-
/**
|
|
251
|
-
|
|
252
|
-
*
|
|
253
|
-
* We return the next proposer's attester address as the node will check if it is the proposer at the next ethereum block,
|
|
254
|
-
* which can be the next slot. If this is the case, then it will send proposals early.
|
|
255
|
-
*/
|
|
256
|
-
public async getProposerAttesterAddressInCurrentOrNextSlot(): Promise<{
|
|
257
|
-
currentSlot: SlotNumber;
|
|
258
|
-
nextSlot: SlotNumber;
|
|
259
|
-
currentProposer: EthAddress | undefined;
|
|
260
|
-
nextProposer: EthAddress | undefined;
|
|
261
|
-
}> {
|
|
281
|
+
/** Returns the current and next L2 slot numbers. */
|
|
282
|
+
public getCurrentAndNextSlot(): { currentSlot: SlotNumber; nextSlot: SlotNumber } {
|
|
262
283
|
const current = this.getEpochAndSlotNow();
|
|
263
284
|
const next = this.getEpochAndSlotInNextL1Slot();
|
|
264
285
|
|
|
265
286
|
return {
|
|
266
|
-
currentProposer: await this.getProposerAttesterAddressAt(current),
|
|
267
|
-
nextProposer: await this.getProposerAttesterAddressAt(next),
|
|
268
287
|
currentSlot: current.slot,
|
|
269
288
|
nextSlot: next.slot,
|
|
270
289
|
};
|
|
@@ -350,9 +369,9 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
350
369
|
const validatorRefreshTime = this.lastValidatorRefresh + validatorRefreshIntervalMs;
|
|
351
370
|
if (validatorRefreshTime < this.dateProvider.now()) {
|
|
352
371
|
const currentSet = await this.rollup.getAttesters();
|
|
353
|
-
this.allValidators = new Set(currentSet);
|
|
372
|
+
this.allValidators = new Set(currentSet.map(v => v.toString()));
|
|
354
373
|
this.lastValidatorRefresh = this.dateProvider.now();
|
|
355
374
|
}
|
|
356
|
-
return Array.from(this.allValidators.keys().map(v => EthAddress.fromString(v))
|
|
375
|
+
return Array.from(this.allValidators.keys()).map(v => EthAddress.fromString(v));
|
|
357
376
|
}
|
|
358
377
|
}
|