@aztec/epoch-cache 0.0.1-commit.9ef841308 → 0.0.1-commit.a89ec08
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 +2 -3
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +1 -3
- package/dest/epoch_cache.d.ts +5 -39
- package/dest/epoch_cache.d.ts.map +1 -1
- package/dest/epoch_cache.js +21 -64
- package/dest/test/test_epoch_cache.d.ts +3 -18
- package/dest/test/test_epoch_cache.d.ts.map +1 -1
- package/dest/test/test_epoch_cache.js +11 -54
- package/package.json +6 -5
- package/src/config.ts +3 -9
- package/src/epoch_cache.ts +19 -83
- package/src/test/test_epoch_cache.ts +12 -79
package/dest/config.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type L1ContractsConfig } from '@aztec/ethereum/config';
|
|
2
2
|
import { type L1ReaderConfig } from '@aztec/ethereum/l1-reader';
|
|
3
|
-
|
|
4
|
-
export type EpochCacheConfig = Pick<L1ReaderConfig & L1ContractsConfig & PipelineConfig, 'l1RpcUrls' | 'l1ChainId' | 'viemPollingIntervalMS' | 'ethereumSlotDuration' | 'l1HttpTimeoutMS' | 'enableProposerPipelining'>;
|
|
3
|
+
export type EpochCacheConfig = Pick<L1ReaderConfig & L1ContractsConfig, 'l1RpcUrls' | 'l1ChainId' | 'viemPollingIntervalMS' | 'l1HttpTimeoutMS' | 'ethereumSlotDuration'>;
|
|
5
4
|
export declare function getEpochCacheConfigEnvVars(): EpochCacheConfig;
|
|
6
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLGlCQUFpQixFQUErQixNQUFNLHdCQUF3QixDQUFDO0FBQzdGLE9BQU8sRUFBRSxLQUFLLGNBQWMsRUFBNEIsTUFBTSwyQkFBMkIsQ0FBQztBQUUxRixNQUFNLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUNqQyxjQUFjLEdBQUcsaUJBQWlCLEVBQ2xDLFdBQVcsR0FBRyxXQUFXLEdBQUcsdUJBQXVCLEdBQUcsaUJBQWlCLEdBQUcsc0JBQXNCLENBQ2pHLENBQUM7QUFFRix3QkFBZ0IsMEJBQTBCLElBQUksZ0JBQWdCLENBRTdEIn0=
|
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,EAAE,KAAK,iBAAiB,EAA+B,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,KAAK,cAAc,EAA4B,MAAM,2BAA2B,CAAC;
|
|
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,iBAAiB,GAAG,sBAAsB,CACjG,CAAC;AAEF,wBAAgB,0BAA0B,IAAI,gBAAgB,CAE7D"}
|
package/dest/config.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config';
|
|
2
2
|
import { getL1ReaderConfigFromEnv } from '@aztec/ethereum/l1-reader';
|
|
3
|
-
import { getPipelineConfigEnvVars } from '@aztec/stdlib/config';
|
|
4
3
|
export function getEpochCacheConfigEnvVars() {
|
|
5
4
|
return {
|
|
6
5
|
...getL1ReaderConfigFromEnv(),
|
|
7
|
-
...getL1ContractsConfigEnvVars()
|
|
8
|
-
...getPipelineConfigEnvVars()
|
|
6
|
+
...getL1ContractsConfigEnvVars()
|
|
9
7
|
};
|
|
10
8
|
}
|
package/dest/epoch_cache.d.ts
CHANGED
|
@@ -4,12 +4,9 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
4
4
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
5
5
|
import { type L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
6
6
|
import { type EpochCacheConfig } from './config.js';
|
|
7
|
-
/** When proposer pipelining is enabled, the proposer builds one slot ahead. */
|
|
8
|
-
export declare const PROPOSER_PIPELINING_SLOT_OFFSET = 1;
|
|
9
|
-
/** Flat return type for compound epoch/slot getters. */
|
|
10
7
|
export type EpochAndSlot = {
|
|
11
|
-
slot: SlotNumber;
|
|
12
8
|
epoch: EpochNumber;
|
|
9
|
+
slot: SlotNumber;
|
|
13
10
|
ts: bigint;
|
|
14
11
|
};
|
|
15
12
|
export type EpochCommitteeInfo = {
|
|
@@ -22,33 +19,18 @@ export type EpochCommitteeInfo = {
|
|
|
22
19
|
export type SlotTag = 'now' | 'next' | SlotNumber;
|
|
23
20
|
export interface EpochCacheInterface {
|
|
24
21
|
getCommittee(slot: SlotTag | undefined): Promise<EpochCommitteeInfo>;
|
|
25
|
-
getSlotNow(): SlotNumber;
|
|
26
|
-
getTargetSlot(): SlotNumber;
|
|
27
|
-
getEpochNow(): EpochNumber;
|
|
28
|
-
getTargetEpoch(): EpochNumber;
|
|
29
22
|
getEpochAndSlotNow(): EpochAndSlot & {
|
|
30
23
|
nowMs: bigint;
|
|
31
24
|
};
|
|
32
25
|
getEpochAndSlotInNextL1Slot(): EpochAndSlot & {
|
|
33
|
-
|
|
34
|
-
};
|
|
35
|
-
/** Returns epoch/slot info for the next L1 slot with pipeline offset applied. */
|
|
36
|
-
getTargetEpochAndSlotInNextL1Slot(): EpochAndSlot & {
|
|
37
|
-
nowSeconds: bigint;
|
|
26
|
+
now: bigint;
|
|
38
27
|
};
|
|
39
|
-
isProposerPipeliningEnabled(): boolean;
|
|
40
|
-
isEscapeHatchOpen(epoch: EpochNumber): Promise<boolean>;
|
|
41
|
-
isEscapeHatchOpenAtSlot(slot: SlotTag): Promise<boolean>;
|
|
42
28
|
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
|
|
43
29
|
computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
|
|
44
30
|
getCurrentAndNextSlot(): {
|
|
45
31
|
currentSlot: SlotNumber;
|
|
46
32
|
nextSlot: SlotNumber;
|
|
47
33
|
};
|
|
48
|
-
getTargetAndNextSlot(): {
|
|
49
|
-
targetSlot: SlotNumber;
|
|
50
|
-
nextSlot: SlotNumber;
|
|
51
|
-
};
|
|
52
34
|
getProposerAttesterAddressInSlot(slot: SlotNumber): Promise<EthAddress | undefined>;
|
|
53
35
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
54
36
|
isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
|
|
@@ -71,39 +53,28 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
71
53
|
protected readonly config: {
|
|
72
54
|
cacheSize: number;
|
|
73
55
|
validatorRefreshIntervalSeconds: number;
|
|
74
|
-
enableProposerPipelining: boolean;
|
|
75
56
|
};
|
|
76
57
|
protected cache: Map<EpochNumber, EpochCommitteeInfo>;
|
|
77
58
|
private allValidators;
|
|
78
59
|
private lastValidatorRefresh;
|
|
79
60
|
private readonly log;
|
|
80
|
-
protected enableProposerPipelining: boolean;
|
|
81
61
|
constructor(rollup: RollupContract, l1constants: L1RollupConstants & {
|
|
82
62
|
lagInEpochsForValidatorSet: number;
|
|
83
63
|
lagInEpochsForRandao: number;
|
|
84
64
|
}, dateProvider?: DateProvider, config?: {
|
|
85
65
|
cacheSize: number;
|
|
86
66
|
validatorRefreshIntervalSeconds: number;
|
|
87
|
-
enableProposerPipelining: boolean;
|
|
88
67
|
});
|
|
89
68
|
static create(rollupOrAddress: EthAddress | RollupContract, config?: EpochCacheConfig, deps?: {
|
|
90
69
|
dateProvider?: DateProvider;
|
|
91
70
|
}): Promise<EpochCache>;
|
|
92
71
|
getL1Constants(): L1RollupConstants;
|
|
93
|
-
isProposerPipeliningEnabled(): boolean;
|
|
94
|
-
getSlotNow(): SlotNumber;
|
|
95
|
-
getTargetSlot(): SlotNumber;
|
|
96
|
-
getEpochNow(): EpochNumber;
|
|
97
|
-
getTargetEpoch(): EpochNumber;
|
|
98
72
|
getEpochAndSlotNow(): EpochAndSlot & {
|
|
99
73
|
nowMs: bigint;
|
|
100
74
|
};
|
|
101
75
|
private getEpochAndSlotAtSlot;
|
|
102
76
|
getEpochAndSlotInNextL1Slot(): EpochAndSlot & {
|
|
103
|
-
|
|
104
|
-
};
|
|
105
|
-
getTargetEpochAndSlotInNextL1Slot(): EpochAndSlot & {
|
|
106
|
-
nowSeconds: bigint;
|
|
77
|
+
now: bigint;
|
|
107
78
|
};
|
|
108
79
|
private getEpochAndSlotAtTimestamp;
|
|
109
80
|
getCommitteeForEpoch(epoch: EpochNumber): Promise<EpochCommitteeInfo>;
|
|
@@ -134,16 +105,11 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
134
105
|
*/
|
|
135
106
|
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
|
|
136
107
|
computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
|
|
137
|
-
/** Returns the current and next L2 slot
|
|
108
|
+
/** Returns the current and next L2 slot numbers. */
|
|
138
109
|
getCurrentAndNextSlot(): {
|
|
139
110
|
currentSlot: SlotNumber;
|
|
140
111
|
nextSlot: SlotNumber;
|
|
141
112
|
};
|
|
142
|
-
/** Returns the taget and next L2 slot in the next L1 slot */
|
|
143
|
-
getTargetAndNextSlot(): {
|
|
144
|
-
targetSlot: SlotNumber;
|
|
145
|
-
nextSlot: SlotNumber;
|
|
146
|
-
};
|
|
147
113
|
/**
|
|
148
114
|
* Get the proposer attester address in the given L2 slot
|
|
149
115
|
* @returns The proposer attester address. If the committee does not exist, we throw a NoCommitteeError.
|
|
@@ -164,4 +130,4 @@ export declare class EpochCache implements EpochCacheInterface {
|
|
|
164
130
|
filterInCommittee(slot: SlotTag, validators: EthAddress[]): Promise<EthAddress[]>;
|
|
165
131
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
166
132
|
}
|
|
167
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
133
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXBvY2hfY2FjaGUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9lcG9jaF9jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQW9CLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDMUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEVBQ0wsS0FBSyxpQkFBaUIsRUFRdkIsTUFBTSw2QkFBNkIsQ0FBQztBQUlyQyxPQUFPLEVBQUUsS0FBSyxnQkFBZ0IsRUFBOEIsTUFBTSxhQUFhLENBQUM7QUFFaEYsTUFBTSxNQUFNLFlBQVksR0FBRztJQUN6QixLQUFLLEVBQUUsV0FBVyxDQUFDO0lBQ25CLElBQUksRUFBRSxVQUFVLENBQUM7SUFDakIsRUFBRSxFQUFFLE1BQU0sQ0FBQztDQUNaLENBQUM7QUFFRixNQUFNLE1BQU0sa0JBQWtCLEdBQUc7SUFDL0IsU0FBUyxFQUFFLFVBQVUsRUFBRSxHQUFHLFNBQVMsQ0FBQztJQUNwQyxJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ2IsS0FBSyxFQUFFLFdBQVcsQ0FBQztJQUNuQiwrREFBK0Q7SUFDL0QsaUJBQWlCLEVBQUUsT0FBTyxDQUFDO0NBQzVCLENBQUM7QUFFRixNQUFNLE1BQU0sT0FBTyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsVUFBVSxDQUFDO0FBRWxELE1BQU0sV0FBVyxtQkFBbUI7SUFDbEMsWUFBWSxDQUFDLElBQUksRUFBRSxPQUFPLEdBQUcsU0FBUyxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JFLGtCQUFrQixJQUFJLFlBQVksR0FBRztRQUFFLEtBQUssRUFBRSxNQUFNLENBQUE7S0FBRSxDQUFDO0lBQ3ZE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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epoch_cache.d.ts","sourceRoot":"","sources":["../src/epoch_cache.ts"],"names":[],"mappings":"AAEA,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,
|
|
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,14 +1,12 @@
|
|
|
1
1
|
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
2
2
|
import { makeL1HttpTransport } from '@aztec/ethereum/client';
|
|
3
3
|
import { NoCommitteeError, RollupContract } from '@aztec/ethereum/contracts';
|
|
4
|
-
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
5
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
6
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
7
6
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
8
|
-
import { getEpochAtSlot, getEpochNumberAtTimestamp, getNextL1SlotTimestamp, getSlotAtTimestamp, getSlotRangeForEpoch, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
7
|
+
import { getEpochAtSlot, getEpochNumberAtTimestamp, getNextL1SlotTimestamp, getSlotAtTimestamp, getSlotRangeForEpoch, getTimestampForSlot, getTimestampRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
|
|
9
8
|
import { createPublicClient, encodeAbiParameters, keccak256 } from 'viem';
|
|
10
9
|
import { getEpochCacheConfigEnvVars } from './config.js';
|
|
11
|
-
/** When proposer pipelining is enabled, the proposer builds one slot ahead. */ export const PROPOSER_PIPELINING_SLOT_OFFSET = 1;
|
|
12
10
|
/**
|
|
13
11
|
* Epoch cache
|
|
14
12
|
*
|
|
@@ -27,11 +25,9 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
27
25
|
allValidators;
|
|
28
26
|
lastValidatorRefresh;
|
|
29
27
|
log;
|
|
30
|
-
enableProposerPipelining;
|
|
31
28
|
constructor(rollup, l1constants, dateProvider = new DateProvider(), config = {
|
|
32
29
|
cacheSize: 12,
|
|
33
|
-
validatorRefreshIntervalSeconds: 60
|
|
34
|
-
enableProposerPipelining: false
|
|
30
|
+
validatorRefreshIntervalSeconds: 60
|
|
35
31
|
}){
|
|
36
32
|
this.rollup = rollup;
|
|
37
33
|
this.l1constants = l1constants;
|
|
@@ -41,10 +37,8 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
41
37
|
this.allValidators = new Set();
|
|
42
38
|
this.lastValidatorRefresh = 0;
|
|
43
39
|
this.log = createLogger('epoch-cache');
|
|
44
|
-
this.enableProposerPipelining = this.config.enableProposerPipelining;
|
|
45
40
|
this.log.debug(`Initialized EpochCache`, {
|
|
46
|
-
l1constants
|
|
47
|
-
enableProposerPipelining: this.enableProposerPipelining
|
|
41
|
+
l1constants
|
|
48
42
|
});
|
|
49
43
|
}
|
|
50
44
|
static async create(rollupOrAddress, config, deps = {}) {
|
|
@@ -87,32 +81,11 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
87
81
|
targetCommitteeSize: Number(targetCommitteeSize),
|
|
88
82
|
rollupManaLimit: Number(rollupManaLimit)
|
|
89
83
|
};
|
|
90
|
-
return new EpochCache(rollup, l1RollupConstants, deps.dateProvider
|
|
91
|
-
cacheSize: 12,
|
|
92
|
-
validatorRefreshIntervalSeconds: 60,
|
|
93
|
-
enableProposerPipelining: config.enableProposerPipelining
|
|
94
|
-
});
|
|
84
|
+
return new EpochCache(rollup, l1RollupConstants, deps.dateProvider);
|
|
95
85
|
}
|
|
96
86
|
getL1Constants() {
|
|
97
87
|
return this.l1constants;
|
|
98
88
|
}
|
|
99
|
-
isProposerPipeliningEnabled() {
|
|
100
|
-
return this.enableProposerPipelining;
|
|
101
|
-
}
|
|
102
|
-
getSlotNow() {
|
|
103
|
-
return this.getEpochAndSlotNow().slot;
|
|
104
|
-
}
|
|
105
|
-
getTargetSlot() {
|
|
106
|
-
const slotNow = this.getSlotNow();
|
|
107
|
-
const offset = this.isProposerPipeliningEnabled() ? PROPOSER_PIPELINING_SLOT_OFFSET : 0;
|
|
108
|
-
return SlotNumber(slotNow + offset);
|
|
109
|
-
}
|
|
110
|
-
getEpochNow() {
|
|
111
|
-
return this.getEpochAndSlotNow().epoch;
|
|
112
|
-
}
|
|
113
|
-
getTargetEpoch() {
|
|
114
|
-
return getEpochAtSlot(this.getTargetSlot(), this.l1constants);
|
|
115
|
-
}
|
|
116
89
|
getEpochAndSlotNow() {
|
|
117
90
|
const nowMs = BigInt(this.dateProvider.now());
|
|
118
91
|
const nowSeconds = nowMs / 1000n;
|
|
@@ -122,36 +95,28 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
122
95
|
};
|
|
123
96
|
}
|
|
124
97
|
getEpochAndSlotAtSlot(slot) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
getEpochAndSlotInNextL1Slot() {
|
|
128
|
-
const nowSeconds = this.dateProvider.nowInSeconds();
|
|
129
|
-
const nextSlotTs = getNextL1SlotTimestamp(nowSeconds, this.l1constants);
|
|
98
|
+
const epoch = getEpochAtSlot(slot, this.l1constants);
|
|
99
|
+
const ts = getTimestampRangeForEpoch(epoch, this.l1constants)[0];
|
|
130
100
|
return {
|
|
131
|
-
|
|
132
|
-
|
|
101
|
+
epoch,
|
|
102
|
+
ts,
|
|
103
|
+
slot
|
|
133
104
|
};
|
|
134
105
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
const result = this.getEpochAndSlotInNextL1Slot();
|
|
140
|
-
const offset = PROPOSER_PIPELINING_SLOT_OFFSET;
|
|
141
|
-
const targetSlot = SlotNumber(result.slot + offset);
|
|
106
|
+
getEpochAndSlotInNextL1Slot() {
|
|
107
|
+
const now = BigInt(this.dateProvider.nowInSeconds());
|
|
108
|
+
const nextSlotTs = getNextL1SlotTimestamp(Number(now), this.l1constants);
|
|
142
109
|
return {
|
|
143
|
-
...
|
|
144
|
-
|
|
145
|
-
epoch: getEpochAtSlot(targetSlot, this.l1constants)
|
|
110
|
+
...this.getEpochAndSlotAtTimestamp(nextSlotTs),
|
|
111
|
+
now
|
|
146
112
|
};
|
|
147
113
|
}
|
|
148
114
|
getEpochAndSlotAtTimestamp(ts) {
|
|
149
115
|
const slot = getSlotAtTimestamp(ts, this.l1constants);
|
|
150
|
-
const epoch = getEpochNumberAtTimestamp(ts, this.l1constants);
|
|
151
116
|
return {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
117
|
+
epoch: getEpochNumberAtTimestamp(ts, this.l1constants),
|
|
118
|
+
ts: getTimestampForSlot(slot, this.l1constants),
|
|
119
|
+
slot
|
|
155
120
|
};
|
|
156
121
|
}
|
|
157
122
|
getCommitteeForEpoch(epoch) {
|
|
@@ -177,7 +142,7 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
177
142
|
* This is a lightweight helper intended for callers that already have a slot number and only
|
|
178
143
|
* need the escape hatch flag (without pulling full committee info).
|
|
179
144
|
*/ async isEscapeHatchOpenAtSlot(slot = 'now') {
|
|
180
|
-
const epoch = slot === 'now' ? this.
|
|
145
|
+
const epoch = slot === 'now' ? this.getEpochAndSlotNow().epoch : slot === 'next' ? this.getEpochAndSlotInNextL1Slot().epoch : getEpochAtSlot(slot, this.l1constants);
|
|
181
146
|
return await this.isEscapeHatchOpen(epoch);
|
|
182
147
|
}
|
|
183
148
|
/**
|
|
@@ -262,19 +227,11 @@ import { getEpochCacheConfigEnvVars } from './config.js';
|
|
|
262
227
|
}
|
|
263
228
|
return BigInt(keccak256(this.getProposerIndexEncoding(epoch, slot, seed))) % size;
|
|
264
229
|
}
|
|
265
|
-
/** Returns the current and next L2 slot
|
|
266
|
-
const
|
|
230
|
+
/** Returns the current and next L2 slot numbers. */ getCurrentAndNextSlot() {
|
|
231
|
+
const current = this.getEpochAndSlotNow();
|
|
267
232
|
const next = this.getEpochAndSlotInNextL1Slot();
|
|
268
233
|
return {
|
|
269
|
-
currentSlot,
|
|
270
|
-
nextSlot: next.slot
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
/** Returns the taget and next L2 slot in the next L1 slot */ getTargetAndNextSlot() {
|
|
274
|
-
const targetSlot = this.getTargetSlot();
|
|
275
|
-
const next = this.getTargetEpochAndSlotInNextL1Slot();
|
|
276
|
-
return {
|
|
277
|
-
targetSlot,
|
|
234
|
+
currentSlot: current.slot,
|
|
278
235
|
nextSlot: next.slot
|
|
279
236
|
};
|
|
280
237
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
3
|
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
4
|
-
import {
|
|
4
|
+
import type { EpochAndSlot, EpochCacheInterface, EpochCommitteeInfo, SlotTag } from '../epoch_cache.js';
|
|
5
5
|
/**
|
|
6
6
|
* A test implementation of EpochCacheInterface that allows manual configuration
|
|
7
7
|
* of committee, proposer, slot, and escape hatch state for use in tests.
|
|
@@ -17,7 +17,6 @@ export declare class TestEpochCache implements EpochCacheInterface {
|
|
|
17
17
|
private seed;
|
|
18
18
|
private registeredValidators;
|
|
19
19
|
private l1Constants;
|
|
20
|
-
private proposerPipeliningEnabled;
|
|
21
20
|
constructor(l1Constants?: Partial<L1RollupConstants>);
|
|
22
21
|
/**
|
|
23
22
|
* Sets the committee members. Used in validation and attestation flows.
|
|
@@ -55,21 +54,12 @@ export declare class TestEpochCache implements EpochCacheInterface {
|
|
|
55
54
|
*/
|
|
56
55
|
setL1Constants(constants: Partial<L1RollupConstants>): this;
|
|
57
56
|
getL1Constants(): L1RollupConstants;
|
|
58
|
-
setProposerPipeliningEnabled(enabled: boolean): void;
|
|
59
57
|
getCommittee(_slot?: SlotTag): Promise<EpochCommitteeInfo>;
|
|
60
|
-
getSlotNow(): SlotNumber;
|
|
61
|
-
getTargetSlot(): SlotNumber;
|
|
62
|
-
getEpochNow(): EpochNumber;
|
|
63
|
-
getTargetEpoch(): EpochNumber;
|
|
64
|
-
isProposerPipeliningEnabled(): boolean;
|
|
65
58
|
getEpochAndSlotNow(): EpochAndSlot & {
|
|
66
59
|
nowMs: bigint;
|
|
67
60
|
};
|
|
68
61
|
getEpochAndSlotInNextL1Slot(): EpochAndSlot & {
|
|
69
|
-
|
|
70
|
-
};
|
|
71
|
-
getTargetEpochAndSlotInNextL1Slot(): EpochAndSlot & {
|
|
72
|
-
nowSeconds: bigint;
|
|
62
|
+
now: bigint;
|
|
73
63
|
};
|
|
74
64
|
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
|
|
75
65
|
computeProposerIndex(slot: SlotNumber, _epoch: EpochNumber, _seed: bigint, size: bigint): bigint;
|
|
@@ -77,15 +67,10 @@ export declare class TestEpochCache implements EpochCacheInterface {
|
|
|
77
67
|
currentSlot: SlotNumber;
|
|
78
68
|
nextSlot: SlotNumber;
|
|
79
69
|
};
|
|
80
|
-
getTargetAndNextSlot(): {
|
|
81
|
-
targetSlot: SlotNumber;
|
|
82
|
-
nextSlot: SlotNumber;
|
|
83
|
-
};
|
|
84
70
|
getProposerAttesterAddressInSlot(_slot: SlotNumber): Promise<EthAddress | undefined>;
|
|
85
71
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
86
72
|
isInCommittee(_slot: SlotTag, validator: EthAddress): Promise<boolean>;
|
|
87
73
|
filterInCommittee(_slot: SlotTag, validators: EthAddress[]): Promise<EthAddress[]>;
|
|
88
|
-
isEscapeHatchOpen(_epoch: EpochNumber): Promise<boolean>;
|
|
89
74
|
isEscapeHatchOpenAtSlot(_slot?: SlotTag): Promise<boolean>;
|
|
90
75
|
}
|
|
91
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
76
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdF9lcG9jaF9jYWNoZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3QvdGVzdF9lcG9jaF9jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUMzRCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBR3JFLE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxtQkFBbUIsRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQWN4Rzs7Ozs7O0dBTUc7QUFDSCxxQkFBYSxjQUFlLFlBQVcsbUJBQW1CO0lBQ3hELE9BQU8sQ0FBQyxTQUFTLENBQW9CO0lBQ3JDLE9BQU8sQ0FBQyxlQUFlLENBQXlCO0lBQ2hELE9BQU8sQ0FBQyxXQUFXLENBQTZCO0lBQ2hELE9BQU8sQ0FBQyxlQUFlLENBQWtCO0lBQ3pDLE9BQU8sQ0FBQyxJQUFJLENBQWM7SUFDMUIsT0FBTyxDQUFDLG9CQUFvQixDQUFvQjtJQUNoRCxPQUFPLENBQUMsV0FBVyxDQUFvQjtJQUV2QyxZQUFZLFdBQVcsR0FBRSxPQUFPLENBQUMsaUJBQWlCLENBQU0sRUFFdkQ7SUFFRDs7O09BR0c7SUFDSCxZQUFZLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxHQUFHLElBQUksQ0FHMUM7SUFFRDs7O09BR0c7SUFDSCxXQUFXLENBQUMsUUFBUSxFQUFFLFVBQVUsR0FBRyxTQUFTLEdBQUcsSUFBSSxDQUdsRDtJQUVEOzs7T0FHRztJQUNILGNBQWMsQ0FBQyxJQUFJLEVBQUUsVUFBVSxHQUFHLElBQUksQ0FHckM7SUFFRDs7O09BR0c7SUFDSCxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsT0FBTyxHQUFHLElBQUksQ0FHdEM7SUFFRDs7O09BR0c7SUFDSCxPQUFPLENBQUMsSUFBSSxFQUFFLE1BQU0sR0FBRyxJQUFJLENBRzFCO0lBRUQ7OztPQUdHO0lBQ0gsdUJBQXVCLENBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxHQUFHLElBQUksQ0FHdEQ7SUFFRDs7O09BR0c7SUFDSCxjQUFjLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLElBQUksQ0FHMUQ7SUFFRCxjQUFjLElBQUksaUJBQWlCLENBRWxDO0lBRUQsWUFBWSxDQUFDLEtBQUssQ0FBQyxFQUFFLE9BQU8sR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FRekQ7SUFFRCxrQkFBa0IsSUFBSSxZQUFZLEdBQUc7UUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFBO0tBQUUsQ0FJckQ7SUFFRCwyQkFBMkIsSUFBSSxZQUFZLEdBQUc7UUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFBO0tBQUUsQ0FPNUQ7SUFFRCx3QkFBd0IsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLE1BQU0sR0FBRyxLQUFLLE1BQU0sRUFBRSxDQUcxRjtJQUVELG9CQUFvQixDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLEdBQUcsTUFBTSxDQUsvRjtJQUVELHFCQUFxQixJQUFJO1FBQUUsV0FBVyxFQUFFLFVBQVUsQ0FBQztRQUFDLFFBQVEsRUFBRSxVQUFVLENBQUE7S0FBRSxDQUt6RTtJQUVELGdDQUFnQyxDQUFDLEtBQUssRUFBRSxVQUFVLEdBQUcsT0FBTyxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsQ0FFbkY7SUFFRCx1QkFBdUIsSUFBSSxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FFL0M7SUFFRCxhQUFhLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FFckU7SUFFRCxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsR0FBRyxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FHakY7SUFFRCx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsRUFBRSxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUV6RDtDQUNGIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test_epoch_cache.d.ts","sourceRoot":"","sources":["../../src/test/test_epoch_cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,OAAO,
|
|
1
|
+
{"version":3,"file":"test_epoch_cache.d.ts","sourceRoot":"","sources":["../../src/test/test_epoch_cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAcxG;;;;;;GAMG;AACH,qBAAa,cAAe,YAAW,mBAAmB;IACxD,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,eAAe,CAAyB;IAChD,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,IAAI,CAAc;IAC1B,OAAO,CAAC,oBAAoB,CAAoB;IAChD,OAAO,CAAC,WAAW,CAAoB;IAEvC,YAAY,WAAW,GAAE,OAAO,CAAC,iBAAiB,CAAM,EAEvD;IAED;;;OAGG;IACH,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,CAG1C;IAED;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,IAAI,CAGlD;IAED;;;OAGG;IACH,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAGrC;IAED;;;OAGG;IACH,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAGtC;IAED;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAG1B;IAED;;;OAGG;IACH,uBAAuB,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,IAAI,CAGtD;IAED;;;OAGG;IACH,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAG1D;IAED,cAAc,IAAI,iBAAiB,CAElC;IAED,YAAY,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAQzD;IAED,kBAAkB,IAAI,YAAY,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAIrD;IAED,2BAA2B,IAAI,YAAY,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAO5D;IAED,wBAAwB,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,MAAM,EAAE,CAG1F;IAED,oBAAoB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAK/F;IAED,qBAAqB,IAAI;QAAE,WAAW,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE,UAAU,CAAA;KAAE,CAKzE;IAED,gCAAgC,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAEnF;IAED,uBAAuB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAE/C;IAED,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAErE;IAED,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAGjF;IAED,uBAAuB,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAEzD;CACF"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import { getEpochAtSlot, getSlotAtTimestamp, getTimestampRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
|
|
3
|
-
import { PROPOSER_PIPELINING_SLOT_OFFSET } from '../epoch_cache.js';
|
|
4
3
|
/** Default L1 constants for testing. */ const DEFAULT_L1_CONSTANTS = {
|
|
5
4
|
l1StartBlock: 0n,
|
|
6
5
|
l1GenesisTime: 0n,
|
|
@@ -25,7 +24,6 @@ import { PROPOSER_PIPELINING_SLOT_OFFSET } from '../epoch_cache.js';
|
|
|
25
24
|
seed = 0n;
|
|
26
25
|
registeredValidators = [];
|
|
27
26
|
l1Constants;
|
|
28
|
-
proposerPipeliningEnabled = false;
|
|
29
27
|
constructor(l1Constants = {}){
|
|
30
28
|
this.l1Constants = {
|
|
31
29
|
...DEFAULT_L1_CONSTANTS,
|
|
@@ -87,9 +85,6 @@ import { PROPOSER_PIPELINING_SLOT_OFFSET } from '../epoch_cache.js';
|
|
|
87
85
|
getL1Constants() {
|
|
88
86
|
return this.l1Constants;
|
|
89
87
|
}
|
|
90
|
-
setProposerPipeliningEnabled(enabled) {
|
|
91
|
-
this.proposerPipeliningEnabled = enabled;
|
|
92
|
-
}
|
|
93
88
|
getCommittee(_slot) {
|
|
94
89
|
const epoch = getEpochAtSlot(this.currentSlot, this.l1Constants);
|
|
95
90
|
return Promise.resolve({
|
|
@@ -99,52 +94,27 @@ import { PROPOSER_PIPELINING_SLOT_OFFSET } from '../epoch_cache.js';
|
|
|
99
94
|
isEscapeHatchOpen: this.escapeHatchOpen
|
|
100
95
|
});
|
|
101
96
|
}
|
|
102
|
-
getSlotNow() {
|
|
103
|
-
return this.currentSlot;
|
|
104
|
-
}
|
|
105
|
-
getTargetSlot() {
|
|
106
|
-
return this.proposerPipeliningEnabled ? SlotNumber(this.currentSlot + PROPOSER_PIPELINING_SLOT_OFFSET) : this.currentSlot;
|
|
107
|
-
}
|
|
108
|
-
getEpochNow() {
|
|
109
|
-
return getEpochAtSlot(this.currentSlot, this.l1Constants);
|
|
110
|
-
}
|
|
111
|
-
getTargetEpoch() {
|
|
112
|
-
return getEpochAtSlot(this.getTargetSlot(), this.l1Constants);
|
|
113
|
-
}
|
|
114
|
-
isProposerPipeliningEnabled() {
|
|
115
|
-
return this.proposerPipeliningEnabled;
|
|
116
|
-
}
|
|
117
97
|
getEpochAndSlotNow() {
|
|
118
|
-
const
|
|
119
|
-
const ts = getTimestampRangeForEpoch(
|
|
98
|
+
const epoch = getEpochAtSlot(this.currentSlot, this.l1Constants);
|
|
99
|
+
const ts = getTimestampRangeForEpoch(epoch, this.l1Constants)[0];
|
|
120
100
|
return {
|
|
121
|
-
epoch
|
|
101
|
+
epoch,
|
|
122
102
|
slot: this.currentSlot,
|
|
123
103
|
ts,
|
|
124
104
|
nowMs: ts * 1000n
|
|
125
105
|
};
|
|
126
106
|
}
|
|
127
107
|
getEpochAndSlotInNextL1Slot() {
|
|
128
|
-
const
|
|
129
|
-
const nextSlotTs =
|
|
108
|
+
const now = getTimestampRangeForEpoch(getEpochAtSlot(this.currentSlot, this.l1Constants), this.l1Constants)[0];
|
|
109
|
+
const nextSlotTs = now + BigInt(this.l1Constants.ethereumSlotDuration);
|
|
130
110
|
const nextSlot = getSlotAtTimestamp(nextSlotTs, this.l1Constants);
|
|
131
|
-
const
|
|
132
|
-
const ts = getTimestampRangeForEpoch(
|
|
111
|
+
const epoch = getEpochAtSlot(nextSlot, this.l1Constants);
|
|
112
|
+
const ts = getTimestampRangeForEpoch(epoch, this.l1Constants)[0];
|
|
133
113
|
return {
|
|
134
|
-
epoch
|
|
114
|
+
epoch,
|
|
135
115
|
slot: nextSlot,
|
|
136
116
|
ts,
|
|
137
|
-
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
getTargetEpochAndSlotInNextL1Slot() {
|
|
141
|
-
const result = this.getEpochAndSlotInNextL1Slot();
|
|
142
|
-
const offset = this.isProposerPipeliningEnabled() ? PROPOSER_PIPELINING_SLOT_OFFSET : 0;
|
|
143
|
-
const targetSlot = SlotNumber(result.slot + offset);
|
|
144
|
-
return {
|
|
145
|
-
...result,
|
|
146
|
-
slot: targetSlot,
|
|
147
|
-
epoch: getEpochAtSlot(targetSlot, this.l1Constants)
|
|
117
|
+
now
|
|
148
118
|
};
|
|
149
119
|
}
|
|
150
120
|
getProposerIndexEncoding(epoch, slot, seed) {
|
|
@@ -158,19 +128,9 @@ import { PROPOSER_PIPELINING_SLOT_OFFSET } from '../epoch_cache.js';
|
|
|
158
128
|
return BigInt(slot) % size;
|
|
159
129
|
}
|
|
160
130
|
getCurrentAndNextSlot() {
|
|
161
|
-
const currentSlot = this.getSlotNow();
|
|
162
|
-
const next = this.getEpochAndSlotInNextL1Slot();
|
|
163
|
-
return {
|
|
164
|
-
currentSlot,
|
|
165
|
-
nextSlot: next.slot
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
getTargetAndNextSlot() {
|
|
169
|
-
const targetSlot = this.getTargetSlot();
|
|
170
|
-
const next = this.getTargetEpochAndSlotInNextL1Slot();
|
|
171
131
|
return {
|
|
172
|
-
|
|
173
|
-
nextSlot:
|
|
132
|
+
currentSlot: this.currentSlot,
|
|
133
|
+
nextSlot: SlotNumber(this.currentSlot + 1)
|
|
174
134
|
};
|
|
175
135
|
}
|
|
176
136
|
getProposerAttesterAddressInSlot(_slot) {
|
|
@@ -186,9 +146,6 @@ import { PROPOSER_PIPELINING_SLOT_OFFSET } from '../epoch_cache.js';
|
|
|
186
146
|
const committeeSet = new Set(this.committee.map((v)=>v.toString()));
|
|
187
147
|
return Promise.resolve(validators.filter((v)=>committeeSet.has(v.toString())));
|
|
188
148
|
}
|
|
189
|
-
isEscapeHatchOpen(_epoch) {
|
|
190
|
-
return Promise.resolve(this.escapeHatchOpen);
|
|
191
|
-
}
|
|
192
149
|
isEscapeHatchOpenAtSlot(_slot) {
|
|
193
150
|
return Promise.resolve(this.escapeHatchOpen);
|
|
194
151
|
}
|
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.a89ec08",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -26,10 +26,11 @@
|
|
|
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.a89ec08",
|
|
30
|
+
"@aztec/foundation": "0.0.1-commit.a89ec08",
|
|
31
|
+
"@aztec/l1-artifacts": "0.0.1-commit.a89ec08",
|
|
32
|
+
"@aztec/stdlib": "0.0.1-commit.a89ec08",
|
|
33
|
+
"@viem/anvil": "^0.0.10",
|
|
33
34
|
"dotenv": "^16.0.3",
|
|
34
35
|
"get-port": "^7.1.0",
|
|
35
36
|
"jest-mock-extended": "^4.0.0",
|
package/src/config.ts
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import { type L1ContractsConfig, getL1ContractsConfigEnvVars } from '@aztec/ethereum/config';
|
|
2
2
|
import { type L1ReaderConfig, getL1ReaderConfigFromEnv } from '@aztec/ethereum/l1-reader';
|
|
3
|
-
import { type PipelineConfig, getPipelineConfigEnvVars } from '@aztec/stdlib/config';
|
|
4
3
|
|
|
5
4
|
export type EpochCacheConfig = Pick<
|
|
6
|
-
L1ReaderConfig & L1ContractsConfig
|
|
7
|
-
| '
|
|
8
|
-
| 'l1ChainId'
|
|
9
|
-
| 'viemPollingIntervalMS'
|
|
10
|
-
| 'ethereumSlotDuration'
|
|
11
|
-
| 'l1HttpTimeoutMS'
|
|
12
|
-
| 'enableProposerPipelining'
|
|
5
|
+
L1ReaderConfig & L1ContractsConfig,
|
|
6
|
+
'l1RpcUrls' | 'l1ChainId' | 'viemPollingIntervalMS' | 'l1HttpTimeoutMS' | 'ethereumSlotDuration'
|
|
13
7
|
>;
|
|
14
8
|
|
|
15
9
|
export function getEpochCacheConfigEnvVars(): EpochCacheConfig {
|
|
16
|
-
return { ...getL1ReaderConfigFromEnv(), ...getL1ContractsConfigEnvVars()
|
|
10
|
+
return { ...getL1ReaderConfigFromEnv(), ...getL1ContractsConfigEnvVars() };
|
|
17
11
|
}
|
package/src/epoch_cache.ts
CHANGED
|
@@ -13,19 +13,16 @@ import {
|
|
|
13
13
|
getSlotAtTimestamp,
|
|
14
14
|
getSlotRangeForEpoch,
|
|
15
15
|
getTimestampForSlot,
|
|
16
|
+
getTimestampRangeForEpoch,
|
|
16
17
|
} from '@aztec/stdlib/epoch-helpers';
|
|
17
18
|
|
|
18
19
|
import { createPublicClient, encodeAbiParameters, keccak256 } from 'viem';
|
|
19
20
|
|
|
20
21
|
import { type EpochCacheConfig, getEpochCacheConfigEnvVars } from './config.js';
|
|
21
22
|
|
|
22
|
-
/** When proposer pipelining is enabled, the proposer builds one slot ahead. */
|
|
23
|
-
export const PROPOSER_PIPELINING_SLOT_OFFSET = 1;
|
|
24
|
-
|
|
25
|
-
/** Flat return type for compound epoch/slot getters. */
|
|
26
23
|
export type EpochAndSlot = {
|
|
27
|
-
slot: SlotNumber;
|
|
28
24
|
epoch: EpochNumber;
|
|
25
|
+
slot: SlotNumber;
|
|
29
26
|
ts: bigint;
|
|
30
27
|
};
|
|
31
28
|
|
|
@@ -41,21 +38,11 @@ export type SlotTag = 'now' | 'next' | SlotNumber;
|
|
|
41
38
|
|
|
42
39
|
export interface EpochCacheInterface {
|
|
43
40
|
getCommittee(slot: SlotTag | undefined): Promise<EpochCommitteeInfo>;
|
|
44
|
-
getSlotNow(): SlotNumber;
|
|
45
|
-
getTargetSlot(): SlotNumber;
|
|
46
|
-
getEpochNow(): EpochNumber;
|
|
47
|
-
getTargetEpoch(): EpochNumber;
|
|
48
41
|
getEpochAndSlotNow(): EpochAndSlot & { nowMs: bigint };
|
|
49
|
-
getEpochAndSlotInNextL1Slot(): EpochAndSlot & {
|
|
50
|
-
/** Returns epoch/slot info for the next L1 slot with pipeline offset applied. */
|
|
51
|
-
getTargetEpochAndSlotInNextL1Slot(): EpochAndSlot & { nowSeconds: bigint };
|
|
52
|
-
isProposerPipeliningEnabled(): boolean;
|
|
53
|
-
isEscapeHatchOpen(epoch: EpochNumber): Promise<boolean>;
|
|
54
|
-
isEscapeHatchOpenAtSlot(slot: SlotTag): Promise<boolean>;
|
|
42
|
+
getEpochAndSlotInNextL1Slot(): EpochAndSlot & { now: bigint };
|
|
55
43
|
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
|
|
56
44
|
computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
|
|
57
45
|
getCurrentAndNextSlot(): { currentSlot: SlotNumber; nextSlot: SlotNumber };
|
|
58
|
-
getTargetAndNextSlot(): { targetSlot: SlotNumber; nextSlot: SlotNumber };
|
|
59
46
|
getProposerAttesterAddressInSlot(slot: SlotNumber): Promise<EthAddress | undefined>;
|
|
60
47
|
getRegisteredValidators(): Promise<EthAddress[]>;
|
|
61
48
|
isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
|
|
@@ -79,8 +66,6 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
79
66
|
private lastValidatorRefresh = 0;
|
|
80
67
|
private readonly log: Logger = createLogger('epoch-cache');
|
|
81
68
|
|
|
82
|
-
protected enableProposerPipelining: boolean;
|
|
83
|
-
|
|
84
69
|
constructor(
|
|
85
70
|
private rollup: RollupContract,
|
|
86
71
|
private readonly l1constants: L1RollupConstants & {
|
|
@@ -88,12 +73,10 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
88
73
|
lagInEpochsForRandao: number;
|
|
89
74
|
},
|
|
90
75
|
private readonly dateProvider: DateProvider = new DateProvider(),
|
|
91
|
-
protected readonly config = { cacheSize: 12, validatorRefreshIntervalSeconds: 60
|
|
76
|
+
protected readonly config = { cacheSize: 12, validatorRefreshIntervalSeconds: 60 },
|
|
92
77
|
) {
|
|
93
|
-
this.enableProposerPipelining = this.config.enableProposerPipelining;
|
|
94
78
|
this.log.debug(`Initialized EpochCache`, {
|
|
95
79
|
l1constants,
|
|
96
|
-
enableProposerPipelining: this.enableProposerPipelining,
|
|
97
80
|
});
|
|
98
81
|
}
|
|
99
82
|
|
|
@@ -153,39 +136,13 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
153
136
|
rollupManaLimit: Number(rollupManaLimit),
|
|
154
137
|
};
|
|
155
138
|
|
|
156
|
-
return new EpochCache(rollup, l1RollupConstants, deps.dateProvider
|
|
157
|
-
cacheSize: 12,
|
|
158
|
-
validatorRefreshIntervalSeconds: 60,
|
|
159
|
-
enableProposerPipelining: config.enableProposerPipelining,
|
|
160
|
-
});
|
|
139
|
+
return new EpochCache(rollup, l1RollupConstants, deps.dateProvider);
|
|
161
140
|
}
|
|
162
141
|
|
|
163
142
|
public getL1Constants(): L1RollupConstants {
|
|
164
143
|
return this.l1constants;
|
|
165
144
|
}
|
|
166
145
|
|
|
167
|
-
public isProposerPipeliningEnabled(): boolean {
|
|
168
|
-
return this.enableProposerPipelining;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
public getSlotNow(): SlotNumber {
|
|
172
|
-
return this.getEpochAndSlotNow().slot;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
public getTargetSlot(): SlotNumber {
|
|
176
|
-
const slotNow = this.getSlotNow();
|
|
177
|
-
const offset = this.isProposerPipeliningEnabled() ? PROPOSER_PIPELINING_SLOT_OFFSET : 0;
|
|
178
|
-
return SlotNumber(slotNow + offset);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
public getEpochNow(): EpochNumber {
|
|
182
|
-
return this.getEpochAndSlotNow().epoch;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
public getTargetEpoch(): EpochNumber {
|
|
186
|
-
return getEpochAtSlot(this.getTargetSlot(), this.l1constants);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
146
|
public getEpochAndSlotNow(): EpochAndSlot & { nowMs: bigint } {
|
|
190
147
|
const nowMs = BigInt(this.dateProvider.now());
|
|
191
148
|
const nowSeconds = nowMs / 1000n;
|
|
@@ -193,33 +150,23 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
193
150
|
}
|
|
194
151
|
|
|
195
152
|
private getEpochAndSlotAtSlot(slot: SlotNumber): EpochAndSlot {
|
|
196
|
-
|
|
153
|
+
const epoch = getEpochAtSlot(slot, this.l1constants);
|
|
154
|
+
const ts = getTimestampRangeForEpoch(epoch, this.l1constants)[0];
|
|
155
|
+
return { epoch, ts, slot };
|
|
197
156
|
}
|
|
198
157
|
|
|
199
|
-
public getEpochAndSlotInNextL1Slot(): EpochAndSlot & {
|
|
200
|
-
const
|
|
201
|
-
const nextSlotTs = getNextL1SlotTimestamp(
|
|
202
|
-
return { ...this.getEpochAndSlotAtTimestamp(nextSlotTs),
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
public getTargetEpochAndSlotInNextL1Slot(): EpochAndSlot & { nowSeconds: bigint } {
|
|
206
|
-
if (!this.isProposerPipeliningEnabled()) {
|
|
207
|
-
return this.getEpochAndSlotInNextL1Slot();
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const result = this.getEpochAndSlotInNextL1Slot();
|
|
211
|
-
const offset = PROPOSER_PIPELINING_SLOT_OFFSET;
|
|
212
|
-
const targetSlot = SlotNumber(result.slot + offset);
|
|
213
|
-
return { ...result, slot: targetSlot, epoch: getEpochAtSlot(targetSlot, this.l1constants) };
|
|
158
|
+
public getEpochAndSlotInNextL1Slot(): EpochAndSlot & { now: bigint } {
|
|
159
|
+
const now = BigInt(this.dateProvider.nowInSeconds());
|
|
160
|
+
const nextSlotTs = getNextL1SlotTimestamp(Number(now), this.l1constants);
|
|
161
|
+
return { ...this.getEpochAndSlotAtTimestamp(nextSlotTs), now };
|
|
214
162
|
}
|
|
215
163
|
|
|
216
164
|
private getEpochAndSlotAtTimestamp(ts: bigint): EpochAndSlot {
|
|
217
165
|
const slot = getSlotAtTimestamp(ts, this.l1constants);
|
|
218
|
-
const epoch = getEpochNumberAtTimestamp(ts, this.l1constants);
|
|
219
166
|
return {
|
|
220
|
-
|
|
221
|
-
epoch,
|
|
167
|
+
epoch: getEpochNumberAtTimestamp(ts, this.l1constants),
|
|
222
168
|
ts: getTimestampForSlot(slot, this.l1constants),
|
|
169
|
+
slot,
|
|
223
170
|
};
|
|
224
171
|
}
|
|
225
172
|
|
|
@@ -252,7 +199,7 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
252
199
|
public async isEscapeHatchOpenAtSlot(slot: SlotTag = 'now'): Promise<boolean> {
|
|
253
200
|
const epoch =
|
|
254
201
|
slot === 'now'
|
|
255
|
-
? this.
|
|
202
|
+
? this.getEpochAndSlotNow().epoch
|
|
256
203
|
: slot === 'next'
|
|
257
204
|
? this.getEpochAndSlotInNextL1Slot().epoch
|
|
258
205
|
: getEpochAtSlot(slot, this.l1constants);
|
|
@@ -287,7 +234,7 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
287
234
|
return epochData;
|
|
288
235
|
}
|
|
289
236
|
|
|
290
|
-
private getEpochAndTimestamp(slot: SlotTag = 'now')
|
|
237
|
+
private getEpochAndTimestamp(slot: SlotTag = 'now') {
|
|
291
238
|
if (slot === 'now') {
|
|
292
239
|
return this.getEpochAndSlotNow();
|
|
293
240
|
} else if (slot === 'next') {
|
|
@@ -337,24 +284,13 @@ export class EpochCache implements EpochCacheInterface {
|
|
|
337
284
|
return BigInt(keccak256(this.getProposerIndexEncoding(epoch, slot, seed))) % size;
|
|
338
285
|
}
|
|
339
286
|
|
|
340
|
-
/** Returns the current and next L2 slot
|
|
287
|
+
/** Returns the current and next L2 slot numbers. */
|
|
341
288
|
public getCurrentAndNextSlot(): { currentSlot: SlotNumber; nextSlot: SlotNumber } {
|
|
342
|
-
const
|
|
289
|
+
const current = this.getEpochAndSlotNow();
|
|
343
290
|
const next = this.getEpochAndSlotInNextL1Slot();
|
|
344
291
|
|
|
345
292
|
return {
|
|
346
|
-
currentSlot,
|
|
347
|
-
nextSlot: next.slot,
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/** Returns the taget and next L2 slot in the next L1 slot */
|
|
352
|
-
public getTargetAndNextSlot(): { targetSlot: SlotNumber; nextSlot: SlotNumber } {
|
|
353
|
-
const targetSlot = this.getTargetSlot();
|
|
354
|
-
const next = this.getTargetEpochAndSlotInNextL1Slot();
|
|
355
|
-
|
|
356
|
-
return {
|
|
357
|
-
targetSlot,
|
|
293
|
+
currentSlot: current.slot,
|
|
358
294
|
nextSlot: next.slot,
|
|
359
295
|
};
|
|
360
296
|
}
|
|
@@ -3,13 +3,7 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
3
3
|
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
4
4
|
import { getEpochAtSlot, getSlotAtTimestamp, getTimestampRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
type EpochAndSlot,
|
|
8
|
-
type EpochCacheInterface,
|
|
9
|
-
type EpochCommitteeInfo,
|
|
10
|
-
PROPOSER_PIPELINING_SLOT_OFFSET,
|
|
11
|
-
type SlotTag,
|
|
12
|
-
} from '../epoch_cache.js';
|
|
6
|
+
import type { EpochAndSlot, EpochCacheInterface, EpochCommitteeInfo, SlotTag } from '../epoch_cache.js';
|
|
13
7
|
|
|
14
8
|
/** Default L1 constants for testing. */
|
|
15
9
|
const DEFAULT_L1_CONSTANTS: L1RollupConstants = {
|
|
@@ -38,7 +32,6 @@ export class TestEpochCache implements EpochCacheInterface {
|
|
|
38
32
|
private seed: bigint = 0n;
|
|
39
33
|
private registeredValidators: EthAddress[] = [];
|
|
40
34
|
private l1Constants: L1RollupConstants;
|
|
41
|
-
private proposerPipeliningEnabled = false;
|
|
42
35
|
|
|
43
36
|
constructor(l1Constants: Partial<L1RollupConstants> = {}) {
|
|
44
37
|
this.l1Constants = { ...DEFAULT_L1_CONSTANTS, ...l1Constants };
|
|
@@ -111,10 +104,6 @@ export class TestEpochCache implements EpochCacheInterface {
|
|
|
111
104
|
return this.l1Constants;
|
|
112
105
|
}
|
|
113
106
|
|
|
114
|
-
setProposerPipeliningEnabled(enabled: boolean): void {
|
|
115
|
-
this.proposerPipeliningEnabled = enabled;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
107
|
getCommittee(_slot?: SlotTag): Promise<EpochCommitteeInfo> {
|
|
119
108
|
const epoch = getEpochAtSlot(this.currentSlot, this.l1Constants);
|
|
120
109
|
return Promise.resolve({
|
|
@@ -125,58 +114,19 @@ export class TestEpochCache implements EpochCacheInterface {
|
|
|
125
114
|
});
|
|
126
115
|
}
|
|
127
116
|
|
|
128
|
-
getSlotNow(): SlotNumber {
|
|
129
|
-
return this.currentSlot;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
getTargetSlot(): SlotNumber {
|
|
133
|
-
return this.proposerPipeliningEnabled
|
|
134
|
-
? SlotNumber(this.currentSlot + PROPOSER_PIPELINING_SLOT_OFFSET)
|
|
135
|
-
: this.currentSlot;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
getEpochNow(): EpochNumber {
|
|
139
|
-
return getEpochAtSlot(this.currentSlot, this.l1Constants);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
getTargetEpoch(): EpochNumber {
|
|
143
|
-
return getEpochAtSlot(this.getTargetSlot(), this.l1Constants);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
isProposerPipeliningEnabled(): boolean {
|
|
147
|
-
return this.proposerPipeliningEnabled;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
117
|
getEpochAndSlotNow(): EpochAndSlot & { nowMs: bigint } {
|
|
151
|
-
const
|
|
152
|
-
const ts = getTimestampRangeForEpoch(
|
|
153
|
-
return {
|
|
154
|
-
epoch: epochNow,
|
|
155
|
-
slot: this.currentSlot,
|
|
156
|
-
ts,
|
|
157
|
-
nowMs: ts * 1000n,
|
|
158
|
-
};
|
|
118
|
+
const epoch = getEpochAtSlot(this.currentSlot, this.l1Constants);
|
|
119
|
+
const ts = getTimestampRangeForEpoch(epoch, this.l1Constants)[0];
|
|
120
|
+
return { epoch, slot: this.currentSlot, ts, nowMs: ts * 1000n };
|
|
159
121
|
}
|
|
160
122
|
|
|
161
|
-
getEpochAndSlotInNextL1Slot(): EpochAndSlot & {
|
|
162
|
-
const
|
|
163
|
-
const nextSlotTs =
|
|
123
|
+
getEpochAndSlotInNextL1Slot(): EpochAndSlot & { now: bigint } {
|
|
124
|
+
const now = getTimestampRangeForEpoch(getEpochAtSlot(this.currentSlot, this.l1Constants), this.l1Constants)[0];
|
|
125
|
+
const nextSlotTs = now + BigInt(this.l1Constants.ethereumSlotDuration);
|
|
164
126
|
const nextSlot = getSlotAtTimestamp(nextSlotTs, this.l1Constants);
|
|
165
|
-
const
|
|
166
|
-
const ts = getTimestampRangeForEpoch(
|
|
167
|
-
return {
|
|
168
|
-
epoch: epochNow,
|
|
169
|
-
slot: nextSlot,
|
|
170
|
-
ts,
|
|
171
|
-
nowSeconds: nowTs,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
getTargetEpochAndSlotInNextL1Slot(): EpochAndSlot & { nowSeconds: bigint } {
|
|
176
|
-
const result = this.getEpochAndSlotInNextL1Slot();
|
|
177
|
-
const offset = this.isProposerPipeliningEnabled() ? PROPOSER_PIPELINING_SLOT_OFFSET : 0;
|
|
178
|
-
const targetSlot = SlotNumber(result.slot + offset);
|
|
179
|
-
return { ...result, slot: targetSlot, epoch: getEpochAtSlot(targetSlot, this.l1Constants) };
|
|
127
|
+
const epoch = getEpochAtSlot(nextSlot, this.l1Constants);
|
|
128
|
+
const ts = getTimestampRangeForEpoch(epoch, this.l1Constants)[0];
|
|
129
|
+
return { epoch, slot: nextSlot, ts, now };
|
|
180
130
|
}
|
|
181
131
|
|
|
182
132
|
getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}` {
|
|
@@ -192,22 +142,9 @@ export class TestEpochCache implements EpochCacheInterface {
|
|
|
192
142
|
}
|
|
193
143
|
|
|
194
144
|
getCurrentAndNextSlot(): { currentSlot: SlotNumber; nextSlot: SlotNumber } {
|
|
195
|
-
const currentSlot = this.getSlotNow();
|
|
196
|
-
const next = this.getEpochAndSlotInNextL1Slot();
|
|
197
|
-
|
|
198
|
-
return {
|
|
199
|
-
currentSlot,
|
|
200
|
-
nextSlot: next.slot,
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
getTargetAndNextSlot(): { targetSlot: SlotNumber; nextSlot: SlotNumber } {
|
|
205
|
-
const targetSlot = this.getTargetSlot();
|
|
206
|
-
const next = this.getTargetEpochAndSlotInNextL1Slot();
|
|
207
|
-
|
|
208
145
|
return {
|
|
209
|
-
|
|
210
|
-
nextSlot:
|
|
146
|
+
currentSlot: this.currentSlot,
|
|
147
|
+
nextSlot: SlotNumber(this.currentSlot + 1),
|
|
211
148
|
};
|
|
212
149
|
}
|
|
213
150
|
|
|
@@ -228,10 +165,6 @@ export class TestEpochCache implements EpochCacheInterface {
|
|
|
228
165
|
return Promise.resolve(validators.filter(v => committeeSet.has(v.toString())));
|
|
229
166
|
}
|
|
230
167
|
|
|
231
|
-
isEscapeHatchOpen(_epoch: EpochNumber): Promise<boolean> {
|
|
232
|
-
return Promise.resolve(this.escapeHatchOpen);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
168
|
isEscapeHatchOpenAtSlot(_slot?: SlotTag): Promise<boolean> {
|
|
236
169
|
return Promise.resolve(this.escapeHatchOpen);
|
|
237
170
|
}
|