@aztec/epoch-cache 0.0.1-commit.dbf9cec → 0.0.1-commit.df81a97b5

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 CHANGED
@@ -1,5 +1,6 @@
1
1
  import { type L1ContractsConfig } from '@aztec/ethereum/config';
2
2
  import { type L1ReaderConfig } from '@aztec/ethereum/l1-reader';
3
- export type EpochCacheConfig = Pick<L1ReaderConfig & L1ContractsConfig, 'l1RpcUrls' | 'l1ChainId' | 'viemPollingIntervalMS' | 'ethereumSlotDuration'>;
3
+ import { type PipelineConfig } from '@aztec/stdlib/config';
4
+ export type EpochCacheConfig = Pick<L1ReaderConfig & L1ContractsConfig & PipelineConfig, 'l1RpcUrls' | 'l1ChainId' | 'viemPollingIntervalMS' | 'ethereumSlotDuration' | 'l1HttpTimeoutMS' | 'enableProposerPipelining'>;
4
5
  export declare function getEpochCacheConfigEnvVars(): EpochCacheConfig;
5
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLGlCQUFpQixFQUErQixNQUFNLHdCQUF3QixDQUFDO0FBQzdGLE9BQU8sRUFBRSxLQUFLLGNBQWMsRUFBNEIsTUFBTSwyQkFBMkIsQ0FBQztBQUUxRixNQUFNLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUNqQyxjQUFjLEdBQUcsaUJBQWlCLEVBQ2xDLFdBQVcsR0FBRyxXQUFXLEdBQUcsdUJBQXVCLEdBQUcsc0JBQXNCLENBQzdFLENBQUM7QUFFRix3QkFBZ0IsMEJBQTBCLElBQUksZ0JBQWdCLENBRTdEIn0=
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLGlCQUFpQixFQUErQixNQUFNLHdCQUF3QixDQUFDO0FBQzdGLE9BQU8sRUFBRSxLQUFLLGNBQWMsRUFBNEIsTUFBTSwyQkFBMkIsQ0FBQztBQUMxRixPQUFPLEVBQUUsS0FBSyxjQUFjLEVBQTRCLE1BQU0sc0JBQXNCLENBQUM7QUFFckYsTUFBTSxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FDakMsY0FBYyxHQUFHLGlCQUFpQixHQUFHLGNBQWMsRUFDakQsV0FBVyxHQUNYLFdBQVcsR0FDWCx1QkFBdUIsR0FDdkIsc0JBQXNCLEdBQ3RCLGlCQUFpQixHQUNqQiwwQkFBMEIsQ0FDN0IsQ0FBQztBQUVGLHdCQUFnQiwwQkFBMEIsSUFBSSxnQkFBZ0IsQ0FFN0QifQ==
@@ -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;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"}
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;AAC1F,OAAO,EAAE,KAAK,cAAc,EAA4B,MAAM,sBAAsB,CAAC;AAErF,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,cAAc,GAAG,iBAAiB,GAAG,cAAc,EACjD,WAAW,GACX,WAAW,GACX,uBAAuB,GACvB,sBAAsB,GACtB,iBAAiB,GACjB,0BAA0B,CAC7B,CAAC;AAEF,wBAAgB,0BAA0B,IAAI,gBAAgB,CAE7D"}
package/dest/config.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config';
2
2
  import { getL1ReaderConfigFromEnv } from '@aztec/ethereum/l1-reader';
3
+ import { getPipelineConfigEnvVars } from '@aztec/stdlib/config';
3
4
  export function getEpochCacheConfigEnvVars() {
4
5
  return {
5
6
  ...getL1ReaderConfigFromEnv(),
6
- ...getL1ContractsConfigEnvVars()
7
+ ...getL1ContractsConfigEnvVars(),
8
+ ...getPipelineConfigEnvVars()
7
9
  };
8
10
  }
@@ -4,9 +4,12 @@ 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. */
7
10
  export type EpochAndSlot = {
8
- epoch: EpochNumber;
9
11
  slot: SlotNumber;
12
+ epoch: EpochNumber;
10
13
  ts: bigint;
11
14
  };
12
15
  export type EpochCommitteeInfo = {
@@ -19,18 +22,33 @@ export type EpochCommitteeInfo = {
19
22
  export type SlotTag = 'now' | 'next' | SlotNumber;
20
23
  export interface EpochCacheInterface {
21
24
  getCommittee(slot: SlotTag | undefined): Promise<EpochCommitteeInfo>;
25
+ getSlotNow(): SlotNumber;
26
+ getTargetSlot(): SlotNumber;
27
+ getEpochNow(): EpochNumber;
28
+ getTargetEpoch(): EpochNumber;
22
29
  getEpochAndSlotNow(): EpochAndSlot & {
23
30
  nowMs: bigint;
24
31
  };
25
32
  getEpochAndSlotInNextL1Slot(): EpochAndSlot & {
26
- now: bigint;
33
+ nowSeconds: bigint;
34
+ };
35
+ /** Returns epoch/slot info for the next L1 slot with pipeline offset applied. */
36
+ getTargetEpochAndSlotInNextL1Slot(): EpochAndSlot & {
37
+ nowSeconds: bigint;
27
38
  };
39
+ isProposerPipeliningEnabled(): boolean;
40
+ isEscapeHatchOpen(epoch: EpochNumber): Promise<boolean>;
41
+ isEscapeHatchOpenAtSlot(slot: SlotTag): Promise<boolean>;
28
42
  getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
29
43
  computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
30
44
  getCurrentAndNextSlot(): {
31
45
  currentSlot: SlotNumber;
32
46
  nextSlot: SlotNumber;
33
47
  };
48
+ getTargetAndNextSlot(): {
49
+ targetSlot: SlotNumber;
50
+ nextSlot: SlotNumber;
51
+ };
34
52
  getProposerAttesterAddressInSlot(slot: SlotNumber): Promise<EthAddress | undefined>;
35
53
  getRegisteredValidators(): Promise<EthAddress[]>;
36
54
  isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
@@ -53,29 +71,39 @@ export declare class EpochCache implements EpochCacheInterface {
53
71
  protected readonly config: {
54
72
  cacheSize: number;
55
73
  validatorRefreshIntervalSeconds: number;
74
+ enableProposerPipelining: boolean;
56
75
  };
57
76
  protected cache: Map<EpochNumber, EpochCommitteeInfo>;
58
77
  private allValidators;
59
78
  private lastValidatorRefresh;
60
79
  private readonly log;
80
+ protected enableProposerPipelining: boolean;
61
81
  constructor(rollup: RollupContract, l1constants: L1RollupConstants & {
62
82
  lagInEpochsForValidatorSet: number;
63
83
  lagInEpochsForRandao: number;
64
84
  }, dateProvider?: DateProvider, config?: {
65
85
  cacheSize: number;
66
86
  validatorRefreshIntervalSeconds: number;
87
+ enableProposerPipelining: boolean;
67
88
  });
68
89
  static create(rollupOrAddress: EthAddress | RollupContract, config?: EpochCacheConfig, deps?: {
69
90
  dateProvider?: DateProvider;
70
91
  }): Promise<EpochCache>;
71
92
  getL1Constants(): L1RollupConstants;
93
+ isProposerPipeliningEnabled(): boolean;
94
+ getSlotNow(): SlotNumber;
95
+ getTargetSlot(): SlotNumber;
96
+ getEpochNow(): EpochNumber;
97
+ getTargetEpoch(): EpochNumber;
72
98
  getEpochAndSlotNow(): EpochAndSlot & {
73
99
  nowMs: bigint;
74
100
  };
75
- nowInSeconds(): bigint;
76
101
  private getEpochAndSlotAtSlot;
77
102
  getEpochAndSlotInNextL1Slot(): EpochAndSlot & {
78
- now: bigint;
103
+ nowSeconds: bigint;
104
+ };
105
+ getTargetEpochAndSlotInNextL1Slot(): EpochAndSlot & {
106
+ nowSeconds: bigint;
79
107
  };
80
108
  private getEpochAndSlotAtTimestamp;
81
109
  getCommitteeForEpoch(epoch: EpochNumber): Promise<EpochCommitteeInfo>;
@@ -106,11 +134,16 @@ export declare class EpochCache implements EpochCacheInterface {
106
134
  */
107
135
  getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
108
136
  computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
109
- /** Returns the current and next L2 slot numbers. */
137
+ /** Returns the current and next L2 slot in next eth L1 Slot. */
110
138
  getCurrentAndNextSlot(): {
111
139
  currentSlot: SlotNumber;
112
140
  nextSlot: SlotNumber;
113
141
  };
142
+ /** Returns the taget and next L2 slot in the next L1 slot */
143
+ getTargetAndNextSlot(): {
144
+ targetSlot: SlotNumber;
145
+ nextSlot: SlotNumber;
146
+ };
114
147
  /**
115
148
  * Get the proposer attester address in the given L2 slot
116
149
  * @returns The proposer attester address. If the committee does not exist, we throw a NoCommitteeError.
@@ -131,4 +164,4 @@ export declare class EpochCache implements EpochCacheInterface {
131
164
  filterInCommittee(slot: SlotTag, validators: EthAddress[]): Promise<EthAddress[]>;
132
165
  getRegisteredValidators(): Promise<EthAddress[]>;
133
166
  }
134
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXBvY2hfY2FjaGUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9lcG9jaF9jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQW9CLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDMUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEVBQ0wsS0FBSyxpQkFBaUIsRUFPdkIsTUFBTSw2QkFBNkIsQ0FBQztBQUlyQyxPQUFPLEVBQUUsS0FBSyxnQkFBZ0IsRUFBOEIsTUFBTSxhQUFhLENBQUM7QUFFaEYsTUFBTSxNQUFNLFlBQVksR0FBRztJQUN6QixLQUFLLEVBQUUsV0FBVyxDQUFDO0lBQ25CLElBQUksRUFBRSxVQUFVLENBQUM7SUFDakIsRUFBRSxFQUFFLE1BQU0sQ0FBQztDQUNaLENBQUM7QUFFRixNQUFNLE1BQU0sa0JBQWtCLEdBQUc7SUFDL0IsU0FBUyxFQUFFLFVBQVUsRUFBRSxHQUFHLFNBQVMsQ0FBQztJQUNwQyxJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ2IsS0FBSyxFQUFFLFdBQVcsQ0FBQztJQUNuQiwrREFBK0Q7SUFDL0QsaUJBQWlCLEVBQUUsT0FBTyxDQUFDO0NBQzVCLENBQUM7QUFFRixNQUFNLE1BQU0sT0FBTyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsVUFBVSxDQUFDO0FBRWxELE1BQU0sV0FBVyxtQkFBbUI7SUFDbEMsWUFBWSxDQUFDLElBQUksRUFBRSxPQUFPLEdBQUcsU0FBUyxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JFLGtCQUFrQixJQUFJLFlBQVksR0FBRztRQUFFLEtBQUssRUFBRSxNQUFNLENBQUE7S0FBRSxDQUFDO0lBQ3ZE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
167
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXBvY2hfY2FjaGUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9lcG9jaF9jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQW9CLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDMUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEVBQ0wsS0FBSyxpQkFBaUIsRUFPdkIsTUFBTSw2QkFBNkIsQ0FBQztBQUlyQyxPQUFPLEVBQUUsS0FBSyxnQkFBZ0IsRUFBOEIsTUFBTSxhQUFhLENBQUM7QUFFaEYsK0VBQStFO0FBQy9FLGVBQU8sTUFBTSwrQkFBK0IsSUFBSSxDQUFDO0FBRWpELHdEQUF3RDtBQUN4RCxNQUFNLE1BQU0sWUFBWSxHQUFHO0lBQ3pCLElBQUksRUFBRSxVQUFVLENBQUM7SUFDakIsS0FBSyxFQUFFLFdBQVcsQ0FBQztJQUNuQixFQUFFLEVBQUUsTUFBTSxDQUFDO0NBQ1osQ0FBQztBQUVGLE1BQU0sTUFBTSxrQkFBa0IsR0FBRztJQUMvQixTQUFTLEVBQUUsVUFBVSxFQUFFLEdBQUcsU0FBUyxDQUFDO0lBQ3BDLElBQUksRUFBRSxNQUFNLENBQUM7SUFDYixLQUFLLEVBQUUsV0FBVyxDQUFDO0lBQ25CLCtEQUErRDtJQUMvRCxpQkFBaUIsRUFBRSxPQUFPLENBQUM7Q0FDNUIsQ0FBQztBQUVGLE1BQU0sTUFBTSxPQUFPLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxVQUFVLENBQUM7QUFFbEQsTUFBTSxXQUFXLG1CQUFtQjtJQUNsQyxZQUFZLENBQUMsSUFBSSxFQUFFLE9BQU8sR0FBRyxTQUFTLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDckUsVUFB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
@@ -1 +1 @@
1
- {"version":3,"file":"epoch_cache.d.ts","sourceRoot":"","sources":["../src/epoch_cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"epoch_cache.d.ts","sourceRoot":"","sources":["../src/epoch_cache.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,14 @@
1
1
  import { createEthereumChain } from '@aztec/ethereum/chain';
2
+ import { makeL1HttpTransport } from '@aztec/ethereum/client';
2
3
  import { NoCommitteeError, RollupContract } from '@aztec/ethereum/contracts';
4
+ import { SlotNumber } from '@aztec/foundation/branded-types';
3
5
  import { EthAddress } from '@aztec/foundation/eth-address';
4
6
  import { createLogger } from '@aztec/foundation/log';
5
7
  import { DateProvider } from '@aztec/foundation/timer';
6
- import { getEpochAtSlot, getEpochNumberAtTimestamp, getSlotAtTimestamp, getSlotRangeForEpoch, getTimestampForSlot, getTimestampRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
7
- import { createPublicClient, encodeAbiParameters, fallback, http, keccak256 } from 'viem';
8
+ import { getEpochAtSlot, getEpochNumberAtTimestamp, getNextL1SlotTimestamp, getSlotAtTimestamp, getSlotRangeForEpoch, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
9
+ import { createPublicClient, encodeAbiParameters, keccak256 } from 'viem';
8
10
  import { getEpochCacheConfigEnvVars } from './config.js';
11
+ /** When proposer pipelining is enabled, the proposer builds one slot ahead. */ export const PROPOSER_PIPELINING_SLOT_OFFSET = 1;
9
12
  /**
10
13
  * Epoch cache
11
14
  *
@@ -24,9 +27,11 @@ import { getEpochCacheConfigEnvVars } from './config.js';
24
27
  allValidators;
25
28
  lastValidatorRefresh;
26
29
  log;
30
+ enableProposerPipelining;
27
31
  constructor(rollup, l1constants, dateProvider = new DateProvider(), config = {
28
32
  cacheSize: 12,
29
- validatorRefreshIntervalSeconds: 60
33
+ validatorRefreshIntervalSeconds: 60,
34
+ enableProposerPipelining: false
30
35
  }){
31
36
  this.rollup = rollup;
32
37
  this.l1constants = l1constants;
@@ -36,8 +41,10 @@ import { getEpochCacheConfigEnvVars } from './config.js';
36
41
  this.allValidators = new Set();
37
42
  this.lastValidatorRefresh = 0;
38
43
  this.log = createLogger('epoch-cache');
44
+ this.enableProposerPipelining = this.config.enableProposerPipelining;
39
45
  this.log.debug(`Initialized EpochCache`, {
40
- l1constants
46
+ l1constants,
47
+ enableProposerPipelining: this.enableProposerPipelining
41
48
  });
42
49
  }
43
50
  static async create(rollupOrAddress, config, deps = {}) {
@@ -50,14 +57,14 @@ import { getEpochCacheConfigEnvVars } from './config.js';
50
57
  const chain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
51
58
  const publicClient = createPublicClient({
52
59
  chain: chain.chainInfo,
53
- transport: fallback(config.l1RpcUrls.map((url)=>http(url, {
54
- batch: false
55
- }))),
60
+ transport: makeL1HttpTransport(config.l1RpcUrls, {
61
+ timeout: config.l1HttpTimeoutMS
62
+ }),
56
63
  pollingInterval: config.viemPollingIntervalMS
57
64
  });
58
65
  rollup = new RollupContract(publicClient, rollupOrAddress.toString());
59
66
  }
60
- const [l1StartBlock, l1GenesisTime, proofSubmissionEpochs, slotDuration, epochDuration, lagInEpochsForValidatorSet, lagInEpochsForRandao, targetCommitteeSize] = await Promise.all([
67
+ const [l1StartBlock, l1GenesisTime, proofSubmissionEpochs, slotDuration, epochDuration, lagInEpochsForValidatorSet, lagInEpochsForRandao, targetCommitteeSize, rollupManaLimit] = await Promise.all([
61
68
  rollup.getL1StartBlock(),
62
69
  rollup.getL1GenesisTime(),
63
70
  rollup.getProofSubmissionEpochs(),
@@ -65,7 +72,8 @@ import { getEpochCacheConfigEnvVars } from './config.js';
65
72
  rollup.getEpochDuration(),
66
73
  rollup.getLagInEpochsForValidatorSet(),
67
74
  rollup.getLagInEpochsForRandao(),
68
- rollup.getTargetCommitteeSize()
75
+ rollup.getTargetCommitteeSize(),
76
+ rollup.getManaLimit()
69
77
  ]);
70
78
  const l1RollupConstants = {
71
79
  l1StartBlock,
@@ -76,13 +84,35 @@ import { getEpochCacheConfigEnvVars } from './config.js';
76
84
  ethereumSlotDuration: config.ethereumSlotDuration,
77
85
  lagInEpochsForValidatorSet: Number(lagInEpochsForValidatorSet),
78
86
  lagInEpochsForRandao: Number(lagInEpochsForRandao),
79
- targetCommitteeSize: Number(targetCommitteeSize)
87
+ targetCommitteeSize: Number(targetCommitteeSize),
88
+ rollupManaLimit: Number(rollupManaLimit)
80
89
  };
81
- return new EpochCache(rollup, l1RollupConstants, deps.dateProvider);
90
+ return new EpochCache(rollup, l1RollupConstants, deps.dateProvider, {
91
+ cacheSize: 12,
92
+ validatorRefreshIntervalSeconds: 60,
93
+ enableProposerPipelining: config.enableProposerPipelining
94
+ });
82
95
  }
83
96
  getL1Constants() {
84
97
  return this.l1constants;
85
98
  }
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
+ }
86
116
  getEpochAndSlotNow() {
87
117
  const nowMs = BigInt(this.dateProvider.now());
88
118
  const nowSeconds = nowMs / 1000n;
@@ -91,32 +121,37 @@ import { getEpochCacheConfigEnvVars } from './config.js';
91
121
  nowMs
92
122
  };
93
123
  }
94
- nowInSeconds() {
95
- return BigInt(Math.floor(this.dateProvider.now() / 1000));
96
- }
97
124
  getEpochAndSlotAtSlot(slot) {
98
- const epoch = getEpochAtSlot(slot, this.l1constants);
99
- const ts = getTimestampRangeForEpoch(epoch, this.l1constants)[0];
100
- return {
101
- epoch,
102
- ts,
103
- slot
104
- };
125
+ return this.getEpochAndSlotAtTimestamp(getTimestampForSlot(slot, this.l1constants));
105
126
  }
106
127
  getEpochAndSlotInNextL1Slot() {
107
- const now = this.nowInSeconds();
108
- const nextSlotTs = now + BigInt(this.l1constants.ethereumSlotDuration);
128
+ const nowSeconds = this.dateProvider.nowInSeconds();
129
+ const nextSlotTs = getNextL1SlotTimestamp(nowSeconds, this.l1constants);
109
130
  return {
110
131
  ...this.getEpochAndSlotAtTimestamp(nextSlotTs),
111
- now
132
+ nowSeconds: BigInt(nowSeconds)
133
+ };
134
+ }
135
+ getTargetEpochAndSlotInNextL1Slot() {
136
+ if (!this.isProposerPipeliningEnabled()) {
137
+ return this.getEpochAndSlotInNextL1Slot();
138
+ }
139
+ const result = this.getEpochAndSlotInNextL1Slot();
140
+ const offset = PROPOSER_PIPELINING_SLOT_OFFSET;
141
+ const targetSlot = SlotNumber(result.slot + offset);
142
+ return {
143
+ ...result,
144
+ slot: targetSlot,
145
+ epoch: getEpochAtSlot(targetSlot, this.l1constants)
112
146
  };
113
147
  }
114
148
  getEpochAndSlotAtTimestamp(ts) {
115
149
  const slot = getSlotAtTimestamp(ts, this.l1constants);
150
+ const epoch = getEpochNumberAtTimestamp(ts, this.l1constants);
116
151
  return {
117
- epoch: getEpochNumberAtTimestamp(ts, this.l1constants),
118
- ts: getTimestampForSlot(slot, this.l1constants),
119
- slot
152
+ slot,
153
+ epoch,
154
+ ts: getTimestampForSlot(slot, this.l1constants)
120
155
  };
121
156
  }
122
157
  getCommitteeForEpoch(epoch) {
@@ -142,7 +177,7 @@ import { getEpochCacheConfigEnvVars } from './config.js';
142
177
  * This is a lightweight helper intended for callers that already have a slot number and only
143
178
  * need the escape hatch flag (without pulling full committee info).
144
179
  */ async isEscapeHatchOpenAtSlot(slot = 'now') {
145
- const epoch = slot === 'now' ? this.getEpochAndSlotNow().epoch : slot === 'next' ? this.getEpochAndSlotInNextL1Slot().epoch : getEpochAtSlot(slot, this.l1constants);
180
+ const epoch = slot === 'now' ? this.getEpochNow() : slot === 'next' ? this.getEpochAndSlotInNextL1Slot().epoch : getEpochAtSlot(slot, this.l1constants);
146
181
  return await this.isEscapeHatchOpen(epoch);
147
182
  }
148
183
  /**
@@ -227,11 +262,19 @@ import { getEpochCacheConfigEnvVars } from './config.js';
227
262
  }
228
263
  return BigInt(keccak256(this.getProposerIndexEncoding(epoch, slot, seed))) % size;
229
264
  }
230
- /** Returns the current and next L2 slot numbers. */ getCurrentAndNextSlot() {
231
- const current = this.getEpochAndSlotNow();
265
+ /** Returns the current and next L2 slot in next eth L1 Slot. */ getCurrentAndNextSlot() {
266
+ const currentSlot = this.getSlotNow();
232
267
  const next = this.getEpochAndSlotInNextL1Slot();
233
268
  return {
234
- currentSlot: current.slot,
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,
235
278
  nextSlot: next.slot
236
279
  };
237
280
  }
@@ -292,10 +335,11 @@ import { getEpochCacheConfigEnvVars } from './config.js';
292
335
  async getRegisteredValidators() {
293
336
  const validatorRefreshIntervalMs = this.config.validatorRefreshIntervalSeconds * 1000;
294
337
  const validatorRefreshTime = this.lastValidatorRefresh + validatorRefreshIntervalMs;
295
- if (validatorRefreshTime < this.dateProvider.now()) {
296
- const currentSet = await this.rollup.getAttesters();
338
+ const now = this.dateProvider.now();
339
+ if (validatorRefreshTime < now) {
340
+ const currentSet = await this.rollup.getAttesters(BigInt(Math.floor(now / 1000)));
297
341
  this.allValidators = new Set(currentSet.map((v)=>v.toString()));
298
- this.lastValidatorRefresh = this.dateProvider.now();
342
+ this.lastValidatorRefresh = now;
299
343
  }
300
344
  return Array.from(this.allValidators.keys()).map((v)=>EthAddress.fromString(v));
301
345
  }
@@ -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 type { EpochAndSlot, EpochCacheInterface, EpochCommitteeInfo, SlotTag } from '../epoch_cache.js';
4
+ import { type EpochAndSlot, type EpochCacheInterface, type EpochCommitteeInfo, type 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,6 +17,7 @@ export declare class TestEpochCache implements EpochCacheInterface {
17
17
  private seed;
18
18
  private registeredValidators;
19
19
  private l1Constants;
20
+ private proposerPipeliningEnabled;
20
21
  constructor(l1Constants?: Partial<L1RollupConstants>);
21
22
  /**
22
23
  * Sets the committee members. Used in validation and attestation flows.
@@ -54,12 +55,21 @@ export declare class TestEpochCache implements EpochCacheInterface {
54
55
  */
55
56
  setL1Constants(constants: Partial<L1RollupConstants>): this;
56
57
  getL1Constants(): L1RollupConstants;
58
+ setProposerPipeliningEnabled(enabled: boolean): void;
57
59
  getCommittee(_slot?: SlotTag): Promise<EpochCommitteeInfo>;
60
+ getSlotNow(): SlotNumber;
61
+ getTargetSlot(): SlotNumber;
62
+ getEpochNow(): EpochNumber;
63
+ getTargetEpoch(): EpochNumber;
64
+ isProposerPipeliningEnabled(): boolean;
58
65
  getEpochAndSlotNow(): EpochAndSlot & {
59
66
  nowMs: bigint;
60
67
  };
61
68
  getEpochAndSlotInNextL1Slot(): EpochAndSlot & {
62
- now: bigint;
69
+ nowSeconds: bigint;
70
+ };
71
+ getTargetEpochAndSlotInNextL1Slot(): EpochAndSlot & {
72
+ nowSeconds: bigint;
63
73
  };
64
74
  getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
65
75
  computeProposerIndex(slot: SlotNumber, _epoch: EpochNumber, _seed: bigint, size: bigint): bigint;
@@ -67,10 +77,15 @@ export declare class TestEpochCache implements EpochCacheInterface {
67
77
  currentSlot: SlotNumber;
68
78
  nextSlot: SlotNumber;
69
79
  };
80
+ getTargetAndNextSlot(): {
81
+ targetSlot: SlotNumber;
82
+ nextSlot: SlotNumber;
83
+ };
70
84
  getProposerAttesterAddressInSlot(_slot: SlotNumber): Promise<EthAddress | undefined>;
71
85
  getRegisteredValidators(): Promise<EthAddress[]>;
72
86
  isInCommittee(_slot: SlotTag, validator: EthAddress): Promise<boolean>;
73
87
  filterInCommittee(_slot: SlotTag, validators: EthAddress[]): Promise<EthAddress[]>;
88
+ isEscapeHatchOpen(_epoch: EpochNumber): Promise<boolean>;
74
89
  isEscapeHatchOpenAtSlot(_slot?: SlotTag): Promise<boolean>;
75
90
  }
76
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdF9lcG9jaF9jYWNoZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3QvdGVzdF9lcG9jaF9jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUMzRCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBR3JFLE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxtQkFBbUIsRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQWF4Rzs7Ozs7O0dBTUc7QUFDSCxxQkFBYSxjQUFlLFlBQVcsbUJBQW1CO0lBQ3hELE9BQU8sQ0FBQyxTQUFTLENBQW9CO0lBQ3JDLE9BQU8sQ0FBQyxlQUFlLENBQXlCO0lBQ2hELE9BQU8sQ0FBQyxXQUFXLENBQTZCO0lBQ2hELE9BQU8sQ0FBQyxlQUFlLENBQWtCO0lBQ3pDLE9BQU8sQ0FBQyxJQUFJLENBQWM7SUFDMUIsT0FBTyxDQUFDLG9CQUFvQixDQUFvQjtJQUNoRCxPQUFPLENBQUMsV0FBVyxDQUFvQjtJQUV2QyxZQUFZLFdBQVcsR0FBRSxPQUFPLENBQUMsaUJBQWlCLENBQU0sRUFFdkQ7SUFFRDs7O09BR0c7SUFDSCxZQUFZLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxHQUFHLElBQUksQ0FHMUM7SUFFRDs7O09BR0c7SUFDSCxXQUFXLENBQUMsUUFBUSxFQUFFLFVBQVUsR0FBRyxTQUFTLEdBQUcsSUFBSSxDQUdsRDtJQUVEOzs7T0FHRztJQUNILGNBQWMsQ0FBQyxJQUFJLEVBQUUsVUFBVSxHQUFHLElBQUksQ0FHckM7SUFFRDs7O09BR0c7SUFDSCxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsT0FBTyxHQUFHLElBQUksQ0FHdEM7SUFFRDs7O09BR0c7SUFDSCxPQUFPLENBQUMsSUFBSSxFQUFFLE1BQU0sR0FBRyxJQUFJLENBRzFCO0lBRUQ7OztPQUdHO0lBQ0gsdUJBQXVCLENBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxHQUFHLElBQUksQ0FHdEQ7SUFFRDs7O09BR0c7SUFDSCxjQUFjLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLElBQUksQ0FHMUQ7SUFFRCxjQUFjLElBQUksaUJBQWlCLENBRWxDO0lBRUQsWUFBWSxDQUFDLEtBQUssQ0FBQyxFQUFFLE9BQU8sR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FRekQ7SUFFRCxrQkFBa0IsSUFBSSxZQUFZLEdBQUc7UUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFBO0tBQUUsQ0FJckQ7SUFFRCwyQkFBMkIsSUFBSSxZQUFZLEdBQUc7UUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFBO0tBQUUsQ0FPNUQ7SUFFRCx3QkFBd0IsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLE1BQU0sR0FBRyxLQUFLLE1BQU0sRUFBRSxDQUcxRjtJQUVELG9CQUFvQixDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLEdBQUcsTUFBTSxDQUsvRjtJQUVELHFCQUFxQixJQUFJO1FBQUUsV0FBVyxFQUFFLFVBQVUsQ0FBQztRQUFDLFFBQVEsRUFBRSxVQUFVLENBQUE7S0FBRSxDQUt6RTtJQUVELGdDQUFnQyxDQUFDLEtBQUssRUFBRSxVQUFVLEdBQUcsT0FBTyxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsQ0FFbkY7SUFFRCx1QkFBdUIsSUFBSSxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FFL0M7SUFFRCxhQUFhLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FFckU7SUFFRCxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsR0FBRyxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FHakY7SUFFRCx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsRUFBRSxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUV6RDtDQUNGIn0=
91
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdF9lcG9jaF9jYWNoZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3QvdGVzdF9lcG9jaF9jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUMzRCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBR3JFLE9BQU8sRUFDTCxLQUFLLFlBQVksRUFDakIsS0FBSyxtQkFBbUIsRUFDeEIsS0FBSyxrQkFBa0IsRUFFdkIsS0FBSyxPQUFPLEVBQ2IsTUFBTSxtQkFBbUIsQ0FBQztBQWMzQjs7Ozs7O0dBTUc7QUFDSCxxQkFBYSxjQUFlLFlBQVcsbUJBQW1CO0lBQ3hELE9BQU8sQ0FBQyxTQUFTLENBQW9CO0lBQ3JDLE9BQU8sQ0FBQyxlQUFlLENBQXlCO0lBQ2hELE9BQU8sQ0FBQyxXQUFXLENBQTZCO0lBQ2hELE9BQU8sQ0FBQyxlQUFlLENBQWtCO0lBQ3pDLE9BQU8sQ0FBQyxJQUFJLENBQWM7SUFDMUIsT0FBTyxDQUFDLG9CQUFvQixDQUFvQjtJQUNoRCxPQUFPLENBQUMsV0FBVyxDQUFvQjtJQUN2QyxPQUFPLENBQUMseUJBQXlCLENBQVM7SUFFMUMsWUFBWSxXQUFXLEdBQUUsT0FBTyxDQUFDLGlCQUFpQixDQUFNLEVBRXZEO0lBRUQ7OztPQUdHO0lBQ0gsWUFBWSxDQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsR0FBRyxJQUFJLENBRzFDO0lBRUQ7OztPQUdHO0lBQ0gsV0FBVyxDQUFDLFFBQVEsRUFBRSxVQUFVLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FHbEQ7SUFFRDs7O09BR0c7SUFDSCxjQUFjLENBQUMsSUFBSSxFQUFFLFVBQVUsR0FBRyxJQUFJLENBR3JDO0lBRUQ7OztPQUdHO0lBQ0gsa0JBQWtCLENBQUMsSUFBSSxFQUFFLE9BQU8sR0FBRyxJQUFJLENBR3RDO0lBRUQ7OztPQUdHO0lBQ0gsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLEdBQUcsSUFBSSxDQUcxQjtJQUVEOzs7T0FHRztJQUNILHVCQUF1QixDQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsR0FBRyxJQUFJLENBR3REO0lBRUQ7OztPQUdHO0lBQ0gsY0FBYyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsaUJBQWlCLENBQUMsR0FBRyxJQUFJLENBRzFEO0lBRUQsY0FBYyxJQUFJLGlCQUFpQixDQUVsQztJQUVELDRCQUE0QixDQUFDLE9BQU8sRUFBRSxPQUFPLEdBQUcsSUFBSSxDQUVuRDtJQUVELFlBQVksQ0FBQyxLQUFLLENBQUMsRUFBRSxPQUFPLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBUXpEO0lBRUQsVUFBVSxJQUFJLFVBQVUsQ0FFdkI7SUFFRCxhQUFhLElBQUksVUFBVSxDQUkxQjtJQUVELFdBQVcsSUFBSSxXQUFXLENBRXpCO0lBRUQsY0FBYyxJQUFJLFdBQVcsQ0FFNUI7SUFFRCwyQkFBMkIsSUFBSSxPQUFPLENBRXJDO0lBRUQsa0JBQWtCLElBQUksWUFBWSxHQUFHO1FBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQTtLQUFFLENBU3JEO0lBRUQsMkJBQTJCLElBQUksWUFBWSxHQUFHO1FBQUUsVUFBVSxFQUFFLE1BQU0sQ0FBQTtLQUFFLENBWW5FO0lBRUQsaUNBQWlDLElBQUksWUFBWSxHQUFHO1FBQUUsVUFBVSxFQUFFLE1BQU0sQ0FBQTtLQUFFLENBS3pFO0lBRUQsd0JBQXdCLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxNQUFNLEdBQUcsS0FBSyxNQUFNLEVBQUUsQ0FHMUY7SUFFRCxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxHQUFHLE1BQU0sQ0FLL0Y7SUFFRCxxQkFBcUIsSUFBSTtRQUFFLFdBQVcsRUFBRSxVQUFVLENBQUM7UUFBQyxRQUFRLEVBQUUsVUFBVSxDQUFBO0tBQUUsQ0FRekU7SUFFRCxvQkFBb0IsSUFBSTtRQUFFLFVBQVUsRUFBRSxVQUFVLENBQUM7UUFBQyxRQUFRLEVBQUUsVUFBVSxDQUFBO0tBQUUsQ0FRdkU7SUFFRCxnQ0FBZ0MsQ0FBQyxLQUFLLEVBQUUsVUFBVSxHQUFHLE9BQU8sQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBRW5GO0lBRUQsdUJBQXVCLElBQUksT0FBTyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBRS9DO0lBRUQsYUFBYSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBRXJFO0lBRUQsaUJBQWlCLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLEdBQUcsT0FBTyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBR2pGO0lBRUQsaUJBQWlCLENBQUMsTUFBTSxFQUFFLFdBQVcsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBRXZEO0lBRUQsdUJBQXVCLENBQUMsS0FBSyxDQUFDLEVBQUUsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FFekQ7Q0FDRiJ9
@@ -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,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAaxG;;;;;;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
+ {"version":3,"file":"test_epoch_cache.d.ts","sourceRoot":"","sources":["../../src/test/test_epoch_cache.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
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';
3
4
  /** Default L1 constants for testing. */ const DEFAULT_L1_CONSTANTS = {
4
5
  l1StartBlock: 0n,
5
6
  l1GenesisTime: 0n,
@@ -7,7 +8,8 @@ import { getEpochAtSlot, getSlotAtTimestamp, getTimestampRangeForEpoch } from '@
7
8
  epochDuration: 16,
8
9
  ethereumSlotDuration: 12,
9
10
  proofSubmissionEpochs: 2,
10
- targetCommitteeSize: 48
11
+ targetCommitteeSize: 48,
12
+ rollupManaLimit: Number.MAX_SAFE_INTEGER
11
13
  };
12
14
  /**
13
15
  * A test implementation of EpochCacheInterface that allows manual configuration
@@ -23,6 +25,7 @@ import { getEpochAtSlot, getSlotAtTimestamp, getTimestampRangeForEpoch } from '@
23
25
  seed = 0n;
24
26
  registeredValidators = [];
25
27
  l1Constants;
28
+ proposerPipeliningEnabled = false;
26
29
  constructor(l1Constants = {}){
27
30
  this.l1Constants = {
28
31
  ...DEFAULT_L1_CONSTANTS,
@@ -84,6 +87,9 @@ import { getEpochAtSlot, getSlotAtTimestamp, getTimestampRangeForEpoch } from '@
84
87
  getL1Constants() {
85
88
  return this.l1Constants;
86
89
  }
90
+ setProposerPipeliningEnabled(enabled) {
91
+ this.proposerPipeliningEnabled = enabled;
92
+ }
87
93
  getCommittee(_slot) {
88
94
  const epoch = getEpochAtSlot(this.currentSlot, this.l1Constants);
89
95
  return Promise.resolve({
@@ -93,27 +99,52 @@ import { getEpochAtSlot, getSlotAtTimestamp, getTimestampRangeForEpoch } from '@
93
99
  isEscapeHatchOpen: this.escapeHatchOpen
94
100
  });
95
101
  }
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
+ }
96
117
  getEpochAndSlotNow() {
97
- const epoch = getEpochAtSlot(this.currentSlot, this.l1Constants);
98
- const ts = getTimestampRangeForEpoch(epoch, this.l1Constants)[0];
118
+ const epochNow = getEpochAtSlot(this.currentSlot, this.l1Constants);
119
+ const ts = getTimestampRangeForEpoch(epochNow, this.l1Constants)[0];
99
120
  return {
100
- epoch,
121
+ epoch: epochNow,
101
122
  slot: this.currentSlot,
102
123
  ts,
103
124
  nowMs: ts * 1000n
104
125
  };
105
126
  }
106
127
  getEpochAndSlotInNextL1Slot() {
107
- const now = getTimestampRangeForEpoch(getEpochAtSlot(this.currentSlot, this.l1Constants), this.l1Constants)[0];
108
- const nextSlotTs = now + BigInt(this.l1Constants.ethereumSlotDuration);
128
+ const nowTs = getTimestampRangeForEpoch(getEpochAtSlot(this.currentSlot, this.l1Constants), this.l1Constants)[0];
129
+ const nextSlotTs = nowTs + BigInt(this.l1Constants.ethereumSlotDuration);
109
130
  const nextSlot = getSlotAtTimestamp(nextSlotTs, this.l1Constants);
110
- const epoch = getEpochAtSlot(nextSlot, this.l1Constants);
111
- const ts = getTimestampRangeForEpoch(epoch, this.l1Constants)[0];
131
+ const epochNow = getEpochAtSlot(nextSlot, this.l1Constants);
132
+ const ts = getTimestampRangeForEpoch(epochNow, this.l1Constants)[0];
112
133
  return {
113
- epoch,
134
+ epoch: epochNow,
114
135
  slot: nextSlot,
115
136
  ts,
116
- now
137
+ nowSeconds: nowTs
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
148
  };
118
149
  }
119
150
  getProposerIndexEncoding(epoch, slot, seed) {
@@ -127,9 +158,19 @@ import { getEpochAtSlot, getSlotAtTimestamp, getTimestampRangeForEpoch } from '@
127
158
  return BigInt(slot) % size;
128
159
  }
129
160
  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();
130
171
  return {
131
- currentSlot: this.currentSlot,
132
- nextSlot: SlotNumber(this.currentSlot + 1)
172
+ targetSlot,
173
+ nextSlot: next.slot
133
174
  };
134
175
  }
135
176
  getProposerAttesterAddressInSlot(_slot) {
@@ -145,6 +186,9 @@ import { getEpochAtSlot, getSlotAtTimestamp, getTimestampRangeForEpoch } from '@
145
186
  const committeeSet = new Set(this.committee.map((v)=>v.toString()));
146
187
  return Promise.resolve(validators.filter((v)=>committeeSet.has(v.toString())));
147
188
  }
189
+ isEscapeHatchOpen(_epoch) {
190
+ return Promise.resolve(this.escapeHatchOpen);
191
+ }
148
192
  isEscapeHatchOpenAtSlot(_slot) {
149
193
  return Promise.resolve(this.escapeHatchOpen);
150
194
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/epoch-cache",
3
- "version": "0.0.1-commit.dbf9cec",
3
+ "version": "0.0.1-commit.df81a97b5",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -26,11 +26,10 @@
26
26
  "../package.common.json"
27
27
  ],
28
28
  "dependencies": {
29
- "@aztec/ethereum": "0.0.1-commit.dbf9cec",
30
- "@aztec/foundation": "0.0.1-commit.dbf9cec",
31
- "@aztec/l1-artifacts": "0.0.1-commit.dbf9cec",
32
- "@aztec/stdlib": "0.0.1-commit.dbf9cec",
33
- "@viem/anvil": "^0.0.10",
29
+ "@aztec/ethereum": "0.0.1-commit.df81a97b5",
30
+ "@aztec/foundation": "0.0.1-commit.df81a97b5",
31
+ "@aztec/l1-artifacts": "0.0.1-commit.df81a97b5",
32
+ "@aztec/stdlib": "0.0.1-commit.df81a97b5",
34
33
  "dotenv": "^16.0.3",
35
34
  "get-port": "^7.1.0",
36
35
  "jest-mock-extended": "^4.0.0",
package/src/config.ts CHANGED
@@ -1,11 +1,17 @@
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';
3
4
 
4
5
  export type EpochCacheConfig = Pick<
5
- L1ReaderConfig & L1ContractsConfig,
6
- 'l1RpcUrls' | 'l1ChainId' | 'viemPollingIntervalMS' | 'ethereumSlotDuration'
6
+ L1ReaderConfig & L1ContractsConfig & PipelineConfig,
7
+ | 'l1RpcUrls'
8
+ | 'l1ChainId'
9
+ | 'viemPollingIntervalMS'
10
+ | 'ethereumSlotDuration'
11
+ | 'l1HttpTimeoutMS'
12
+ | 'enableProposerPipelining'
7
13
  >;
8
14
 
9
15
  export function getEpochCacheConfigEnvVars(): EpochCacheConfig {
10
- return { ...getL1ReaderConfigFromEnv(), ...getL1ContractsConfigEnvVars() };
16
+ return { ...getL1ReaderConfigFromEnv(), ...getL1ContractsConfigEnvVars(), ...getPipelineConfigEnvVars() };
11
17
  }
@@ -1,4 +1,5 @@
1
1
  import { createEthereumChain } from '@aztec/ethereum/chain';
2
+ import { makeL1HttpTransport } from '@aztec/ethereum/client';
2
3
  import { NoCommitteeError, RollupContract } from '@aztec/ethereum/contracts';
3
4
  import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
4
5
  import { EthAddress } from '@aztec/foundation/eth-address';
@@ -8,19 +9,23 @@ import {
8
9
  type L1RollupConstants,
9
10
  getEpochAtSlot,
10
11
  getEpochNumberAtTimestamp,
12
+ getNextL1SlotTimestamp,
11
13
  getSlotAtTimestamp,
12
14
  getSlotRangeForEpoch,
13
15
  getTimestampForSlot,
14
- getTimestampRangeForEpoch,
15
16
  } from '@aztec/stdlib/epoch-helpers';
16
17
 
17
- import { createPublicClient, encodeAbiParameters, fallback, http, keccak256 } from 'viem';
18
+ import { createPublicClient, encodeAbiParameters, keccak256 } from 'viem';
18
19
 
19
20
  import { type EpochCacheConfig, getEpochCacheConfigEnvVars } from './config.js';
20
21
 
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. */
21
26
  export type EpochAndSlot = {
22
- epoch: EpochNumber;
23
27
  slot: SlotNumber;
28
+ epoch: EpochNumber;
24
29
  ts: bigint;
25
30
  };
26
31
 
@@ -36,11 +41,21 @@ export type SlotTag = 'now' | 'next' | SlotNumber;
36
41
 
37
42
  export interface EpochCacheInterface {
38
43
  getCommittee(slot: SlotTag | undefined): Promise<EpochCommitteeInfo>;
44
+ getSlotNow(): SlotNumber;
45
+ getTargetSlot(): SlotNumber;
46
+ getEpochNow(): EpochNumber;
47
+ getTargetEpoch(): EpochNumber;
39
48
  getEpochAndSlotNow(): EpochAndSlot & { nowMs: bigint };
40
- getEpochAndSlotInNextL1Slot(): EpochAndSlot & { now: bigint };
49
+ getEpochAndSlotInNextL1Slot(): EpochAndSlot & { nowSeconds: bigint };
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>;
41
55
  getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}`;
42
56
  computeProposerIndex(slot: SlotNumber, epoch: EpochNumber, seed: bigint, size: bigint): bigint;
43
57
  getCurrentAndNextSlot(): { currentSlot: SlotNumber; nextSlot: SlotNumber };
58
+ getTargetAndNextSlot(): { targetSlot: SlotNumber; nextSlot: SlotNumber };
44
59
  getProposerAttesterAddressInSlot(slot: SlotNumber): Promise<EthAddress | undefined>;
45
60
  getRegisteredValidators(): Promise<EthAddress[]>;
46
61
  isInCommittee(slot: SlotTag, validator: EthAddress): Promise<boolean>;
@@ -64,6 +79,8 @@ export class EpochCache implements EpochCacheInterface {
64
79
  private lastValidatorRefresh = 0;
65
80
  private readonly log: Logger = createLogger('epoch-cache');
66
81
 
82
+ protected enableProposerPipelining: boolean;
83
+
67
84
  constructor(
68
85
  private rollup: RollupContract,
69
86
  private readonly l1constants: L1RollupConstants & {
@@ -71,10 +88,12 @@ export class EpochCache implements EpochCacheInterface {
71
88
  lagInEpochsForRandao: number;
72
89
  },
73
90
  private readonly dateProvider: DateProvider = new DateProvider(),
74
- protected readonly config = { cacheSize: 12, validatorRefreshIntervalSeconds: 60 },
91
+ protected readonly config = { cacheSize: 12, validatorRefreshIntervalSeconds: 60, enableProposerPipelining: false },
75
92
  ) {
93
+ this.enableProposerPipelining = this.config.enableProposerPipelining;
76
94
  this.log.debug(`Initialized EpochCache`, {
77
95
  l1constants,
96
+ enableProposerPipelining: this.enableProposerPipelining,
78
97
  });
79
98
  }
80
99
 
@@ -93,7 +112,7 @@ export class EpochCache implements EpochCacheInterface {
93
112
  const chain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
94
113
  const publicClient = createPublicClient({
95
114
  chain: chain.chainInfo,
96
- transport: fallback(config.l1RpcUrls.map(url => http(url, { batch: false }))),
115
+ transport: makeL1HttpTransport(config.l1RpcUrls, { timeout: config.l1HttpTimeoutMS }),
97
116
  pollingInterval: config.viemPollingIntervalMS,
98
117
  });
99
118
  rollup = new RollupContract(publicClient, rollupOrAddress.toString());
@@ -108,6 +127,7 @@ export class EpochCache implements EpochCacheInterface {
108
127
  lagInEpochsForValidatorSet,
109
128
  lagInEpochsForRandao,
110
129
  targetCommitteeSize,
130
+ rollupManaLimit,
111
131
  ] = await Promise.all([
112
132
  rollup.getL1StartBlock(),
113
133
  rollup.getL1GenesisTime(),
@@ -117,6 +137,7 @@ export class EpochCache implements EpochCacheInterface {
117
137
  rollup.getLagInEpochsForValidatorSet(),
118
138
  rollup.getLagInEpochsForRandao(),
119
139
  rollup.getTargetCommitteeSize(),
140
+ rollup.getManaLimit(),
120
141
  ] as const);
121
142
 
122
143
  const l1RollupConstants = {
@@ -129,43 +150,76 @@ export class EpochCache implements EpochCacheInterface {
129
150
  lagInEpochsForValidatorSet: Number(lagInEpochsForValidatorSet),
130
151
  lagInEpochsForRandao: Number(lagInEpochsForRandao),
131
152
  targetCommitteeSize: Number(targetCommitteeSize),
153
+ rollupManaLimit: Number(rollupManaLimit),
132
154
  };
133
155
 
134
- return new EpochCache(rollup, l1RollupConstants, deps.dateProvider);
156
+ return new EpochCache(rollup, l1RollupConstants, deps.dateProvider, {
157
+ cacheSize: 12,
158
+ validatorRefreshIntervalSeconds: 60,
159
+ enableProposerPipelining: config.enableProposerPipelining,
160
+ });
135
161
  }
136
162
 
137
163
  public getL1Constants(): L1RollupConstants {
138
164
  return this.l1constants;
139
165
  }
140
166
 
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
+
141
189
  public getEpochAndSlotNow(): EpochAndSlot & { nowMs: bigint } {
142
190
  const nowMs = BigInt(this.dateProvider.now());
143
191
  const nowSeconds = nowMs / 1000n;
144
192
  return { ...this.getEpochAndSlotAtTimestamp(nowSeconds), nowMs };
145
193
  }
146
194
 
147
- public nowInSeconds(): bigint {
148
- return BigInt(Math.floor(this.dateProvider.now() / 1000));
195
+ private getEpochAndSlotAtSlot(slot: SlotNumber): EpochAndSlot {
196
+ return this.getEpochAndSlotAtTimestamp(getTimestampForSlot(slot, this.l1constants));
149
197
  }
150
198
 
151
- private getEpochAndSlotAtSlot(slot: SlotNumber): EpochAndSlot {
152
- const epoch = getEpochAtSlot(slot, this.l1constants);
153
- const ts = getTimestampRangeForEpoch(epoch, this.l1constants)[0];
154
- return { epoch, ts, slot };
199
+ public getEpochAndSlotInNextL1Slot(): EpochAndSlot & { nowSeconds: bigint } {
200
+ const nowSeconds = this.dateProvider.nowInSeconds();
201
+ const nextSlotTs = getNextL1SlotTimestamp(nowSeconds, this.l1constants);
202
+ return { ...this.getEpochAndSlotAtTimestamp(nextSlotTs), nowSeconds: BigInt(nowSeconds) };
155
203
  }
156
204
 
157
- public getEpochAndSlotInNextL1Slot(): EpochAndSlot & { now: bigint } {
158
- const now = this.nowInSeconds();
159
- const nextSlotTs = now + BigInt(this.l1constants.ethereumSlotDuration);
160
- return { ...this.getEpochAndSlotAtTimestamp(nextSlotTs), now };
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) };
161
214
  }
162
215
 
163
216
  private getEpochAndSlotAtTimestamp(ts: bigint): EpochAndSlot {
164
217
  const slot = getSlotAtTimestamp(ts, this.l1constants);
218
+ const epoch = getEpochNumberAtTimestamp(ts, this.l1constants);
165
219
  return {
166
- epoch: getEpochNumberAtTimestamp(ts, this.l1constants),
167
- ts: getTimestampForSlot(slot, this.l1constants),
168
220
  slot,
221
+ epoch,
222
+ ts: getTimestampForSlot(slot, this.l1constants),
169
223
  };
170
224
  }
171
225
 
@@ -198,7 +252,7 @@ export class EpochCache implements EpochCacheInterface {
198
252
  public async isEscapeHatchOpenAtSlot(slot: SlotTag = 'now'): Promise<boolean> {
199
253
  const epoch =
200
254
  slot === 'now'
201
- ? this.getEpochAndSlotNow().epoch
255
+ ? this.getEpochNow()
202
256
  : slot === 'next'
203
257
  ? this.getEpochAndSlotInNextL1Slot().epoch
204
258
  : getEpochAtSlot(slot, this.l1constants);
@@ -233,7 +287,7 @@ export class EpochCache implements EpochCacheInterface {
233
287
  return epochData;
234
288
  }
235
289
 
236
- private getEpochAndTimestamp(slot: SlotTag = 'now') {
290
+ private getEpochAndTimestamp(slot: SlotTag = 'now'): { epoch: EpochNumber; ts: bigint } {
237
291
  if (slot === 'now') {
238
292
  return this.getEpochAndSlotNow();
239
293
  } else if (slot === 'next') {
@@ -283,13 +337,24 @@ export class EpochCache implements EpochCacheInterface {
283
337
  return BigInt(keccak256(this.getProposerIndexEncoding(epoch, slot, seed))) % size;
284
338
  }
285
339
 
286
- /** Returns the current and next L2 slot numbers. */
340
+ /** Returns the current and next L2 slot in next eth L1 Slot. */
287
341
  public getCurrentAndNextSlot(): { currentSlot: SlotNumber; nextSlot: SlotNumber } {
288
- const current = this.getEpochAndSlotNow();
342
+ const currentSlot = this.getSlotNow();
289
343
  const next = this.getEpochAndSlotInNextL1Slot();
290
344
 
291
345
  return {
292
- currentSlot: current.slot,
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
358
  nextSlot: next.slot,
294
359
  };
295
360
  }
@@ -372,10 +437,11 @@ export class EpochCache implements EpochCacheInterface {
372
437
  async getRegisteredValidators(): Promise<EthAddress[]> {
373
438
  const validatorRefreshIntervalMs = this.config.validatorRefreshIntervalSeconds * 1000;
374
439
  const validatorRefreshTime = this.lastValidatorRefresh + validatorRefreshIntervalMs;
375
- if (validatorRefreshTime < this.dateProvider.now()) {
376
- const currentSet = await this.rollup.getAttesters();
440
+ const now = this.dateProvider.now();
441
+ if (validatorRefreshTime < now) {
442
+ const currentSet = await this.rollup.getAttesters(BigInt(Math.floor(now / 1000)));
377
443
  this.allValidators = new Set(currentSet.map(v => v.toString()));
378
- this.lastValidatorRefresh = this.dateProvider.now();
444
+ this.lastValidatorRefresh = now;
379
445
  }
380
446
  return Array.from(this.allValidators.keys()).map(v => EthAddress.fromString(v));
381
447
  }
@@ -3,7 +3,13 @@ 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 type { EpochAndSlot, EpochCacheInterface, EpochCommitteeInfo, SlotTag } from '../epoch_cache.js';
6
+ import {
7
+ type EpochAndSlot,
8
+ type EpochCacheInterface,
9
+ type EpochCommitteeInfo,
10
+ PROPOSER_PIPELINING_SLOT_OFFSET,
11
+ type SlotTag,
12
+ } from '../epoch_cache.js';
7
13
 
8
14
  /** Default L1 constants for testing. */
9
15
  const DEFAULT_L1_CONSTANTS: L1RollupConstants = {
@@ -14,6 +20,7 @@ const DEFAULT_L1_CONSTANTS: L1RollupConstants = {
14
20
  ethereumSlotDuration: 12,
15
21
  proofSubmissionEpochs: 2,
16
22
  targetCommitteeSize: 48,
23
+ rollupManaLimit: Number.MAX_SAFE_INTEGER,
17
24
  };
18
25
 
19
26
  /**
@@ -31,6 +38,7 @@ export class TestEpochCache implements EpochCacheInterface {
31
38
  private seed: bigint = 0n;
32
39
  private registeredValidators: EthAddress[] = [];
33
40
  private l1Constants: L1RollupConstants;
41
+ private proposerPipeliningEnabled = false;
34
42
 
35
43
  constructor(l1Constants: Partial<L1RollupConstants> = {}) {
36
44
  this.l1Constants = { ...DEFAULT_L1_CONSTANTS, ...l1Constants };
@@ -103,6 +111,10 @@ export class TestEpochCache implements EpochCacheInterface {
103
111
  return this.l1Constants;
104
112
  }
105
113
 
114
+ setProposerPipeliningEnabled(enabled: boolean): void {
115
+ this.proposerPipeliningEnabled = enabled;
116
+ }
117
+
106
118
  getCommittee(_slot?: SlotTag): Promise<EpochCommitteeInfo> {
107
119
  const epoch = getEpochAtSlot(this.currentSlot, this.l1Constants);
108
120
  return Promise.resolve({
@@ -113,19 +125,58 @@ export class TestEpochCache implements EpochCacheInterface {
113
125
  });
114
126
  }
115
127
 
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
+
116
150
  getEpochAndSlotNow(): EpochAndSlot & { nowMs: bigint } {
117
- const epoch = getEpochAtSlot(this.currentSlot, this.l1Constants);
118
- const ts = getTimestampRangeForEpoch(epoch, this.l1Constants)[0];
119
- return { epoch, slot: this.currentSlot, ts, nowMs: ts * 1000n };
151
+ const epochNow = getEpochAtSlot(this.currentSlot, this.l1Constants);
152
+ const ts = getTimestampRangeForEpoch(epochNow, this.l1Constants)[0];
153
+ return {
154
+ epoch: epochNow,
155
+ slot: this.currentSlot,
156
+ ts,
157
+ nowMs: ts * 1000n,
158
+ };
120
159
  }
121
160
 
122
- getEpochAndSlotInNextL1Slot(): EpochAndSlot & { now: bigint } {
123
- const now = getTimestampRangeForEpoch(getEpochAtSlot(this.currentSlot, this.l1Constants), this.l1Constants)[0];
124
- const nextSlotTs = now + BigInt(this.l1Constants.ethereumSlotDuration);
161
+ getEpochAndSlotInNextL1Slot(): EpochAndSlot & { nowSeconds: bigint } {
162
+ const nowTs = getTimestampRangeForEpoch(getEpochAtSlot(this.currentSlot, this.l1Constants), this.l1Constants)[0];
163
+ const nextSlotTs = nowTs + BigInt(this.l1Constants.ethereumSlotDuration);
125
164
  const nextSlot = getSlotAtTimestamp(nextSlotTs, this.l1Constants);
126
- const epoch = getEpochAtSlot(nextSlot, this.l1Constants);
127
- const ts = getTimestampRangeForEpoch(epoch, this.l1Constants)[0];
128
- return { epoch, slot: nextSlot, ts, now };
165
+ const epochNow = getEpochAtSlot(nextSlot, this.l1Constants);
166
+ const ts = getTimestampRangeForEpoch(epochNow, this.l1Constants)[0];
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) };
129
180
  }
130
181
 
131
182
  getProposerIndexEncoding(epoch: EpochNumber, slot: SlotNumber, seed: bigint): `0x${string}` {
@@ -141,9 +192,22 @@ export class TestEpochCache implements EpochCacheInterface {
141
192
  }
142
193
 
143
194
  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
+
144
208
  return {
145
- currentSlot: this.currentSlot,
146
- nextSlot: SlotNumber(this.currentSlot + 1),
209
+ targetSlot,
210
+ nextSlot: next.slot,
147
211
  };
148
212
  }
149
213
 
@@ -164,6 +228,10 @@ export class TestEpochCache implements EpochCacheInterface {
164
228
  return Promise.resolve(validators.filter(v => committeeSet.has(v.toString())));
165
229
  }
166
230
 
231
+ isEscapeHatchOpen(_epoch: EpochNumber): Promise<boolean> {
232
+ return Promise.resolve(this.escapeHatchOpen);
233
+ }
234
+
167
235
  isEscapeHatchOpenAtSlot(_slot?: SlotTag): Promise<boolean> {
168
236
  return Promise.resolve(this.escapeHatchOpen);
169
237
  }