@aztec/stdlib 5.0.0-nightly.20260409 → 5.0.0-nightly.20260410

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.
Files changed (61) hide show
  1. package/dest/interfaces/aztec-node-admin.d.ts +3 -11
  2. package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
  3. package/dest/interfaces/aztec-node-admin.js +1 -2
  4. package/dest/interfaces/proving-job.d.ts +166 -166
  5. package/dest/interfaces/slasher.d.ts +1 -10
  6. package/dest/interfaces/slasher.d.ts.map +1 -1
  7. package/dest/interfaces/slasher.js +0 -2
  8. package/dest/interfaces/validator.d.ts +3 -6
  9. package/dest/interfaces/validator.d.ts.map +1 -1
  10. package/dest/l1-contracts/index.d.ts +2 -2
  11. package/dest/l1-contracts/index.d.ts.map +1 -1
  12. package/dest/l1-contracts/index.js +1 -1
  13. package/dest/p2p/checkpoint_proposal.d.ts +2 -2
  14. package/dest/p2p/checkpoint_proposal.d.ts.map +1 -1
  15. package/dest/p2p/checkpoint_proposal.js +3 -15
  16. package/dest/slashing/index.d.ts +2 -3
  17. package/dest/slashing/index.d.ts.map +1 -1
  18. package/dest/slashing/index.js +1 -2
  19. package/dest/slashing/serialization.d.ts +2 -6
  20. package/dest/slashing/serialization.d.ts.map +1 -1
  21. package/dest/slashing/serialization.js +0 -60
  22. package/dest/slashing/types.d.ts +4 -90
  23. package/dest/slashing/types.d.ts.map +1 -1
  24. package/dest/slashing/types.js +0 -14
  25. package/dest/slashing/{tally.d.ts → votes.d.ts} +1 -1
  26. package/dest/slashing/{tally.d.ts.map → votes.d.ts.map} +1 -1
  27. package/dest/slashing/{tally.js → votes.js} +1 -1
  28. package/dest/tests/mocks.d.ts +1 -1
  29. package/dest/tests/mocks.d.ts.map +1 -1
  30. package/dest/tests/mocks.js +11 -16
  31. package/dest/timetable/index.d.ts +2 -1
  32. package/dest/timetable/index.d.ts.map +1 -1
  33. package/dest/timetable/index.js +6 -2
  34. package/dest/world-state/genesis_data.d.ts +11 -0
  35. package/dest/world-state/genesis_data.d.ts.map +1 -0
  36. package/dest/world-state/genesis_data.js +4 -0
  37. package/dest/world-state/index.d.ts +2 -1
  38. package/dest/world-state/index.d.ts.map +1 -1
  39. package/dest/world-state/index.js +1 -0
  40. package/package.json +8 -8
  41. package/src/interfaces/aztec-node-admin.ts +3 -6
  42. package/src/interfaces/slasher.ts +0 -6
  43. package/src/interfaces/validator.ts +1 -4
  44. package/src/l1-contracts/index.ts +1 -1
  45. package/src/p2p/checkpoint_proposal.ts +10 -26
  46. package/src/slashing/index.ts +1 -2
  47. package/src/slashing/serialization.ts +1 -81
  48. package/src/slashing/types.ts +3 -35
  49. package/src/slashing/{tally.ts → votes.ts} +1 -1
  50. package/src/tests/mocks.ts +12 -10
  51. package/src/timetable/index.ts +7 -2
  52. package/src/world-state/genesis_data.ts +15 -0
  53. package/src/world-state/index.ts +1 -0
  54. package/dest/l1-contracts/slash_factory.d.ts +0 -45
  55. package/dest/l1-contracts/slash_factory.d.ts.map +0 -1
  56. package/dest/l1-contracts/slash_factory.js +0 -158
  57. package/dest/slashing/empire.d.ts +0 -31
  58. package/dest/slashing/empire.d.ts.map +0 -1
  59. package/dest/slashing/empire.js +0 -87
  60. package/src/l1-contracts/slash_factory.ts +0 -180
  61. package/src/slashing/empire.ts +0 -104
@@ -338,27 +338,22 @@ export const makeBlockProposal = (options)=>{
338
338
  const signer = options?.signer ?? Secp256k1Signer.random();
339
339
  return BlockProposal.createProposalFromSigner(blockHeader, indexWithinCheckpoint, inHash, archiveRoot, txHashes, txs, (_payload, _context)=>Promise.resolve(signer.signMessage(_payload)));
340
340
  };
341
- export const makeCheckpointProposal = (options)=>{
342
- const blockHeader = options?.lastBlock?.blockHeader ?? makeBlockHeader(1);
341
+ export const makeCheckpointProposal = async (options)=>{
343
342
  const checkpointHeader = options?.checkpointHeader ?? makeCheckpointHeader(1);
344
343
  const archiveRoot = options?.archiveRoot ?? Fr.random();
345
344
  const feeAssetPriceModifier = options?.feeAssetPriceModifier ?? 0n;
346
345
  const signer = options?.signer ?? Secp256k1Signer.random();
347
- // Build lastBlock info if provided
348
- const lastBlockInfo = options?.lastBlock ? {
349
- blockHeader,
346
+ // Build a signed block proposal if lastBlock options are provided
347
+ const lastBlockProposal = options?.lastBlock ? await makeBlockProposal({
348
+ blockHeader: options.lastBlock.blockHeader,
350
349
  indexWithinCheckpoint: options.lastBlock.indexWithinCheckpoint ?? IndexWithinCheckpoint(4),
351
- txHashes: options.lastBlock.txHashes ?? [
352
- 0,
353
- 1,
354
- 2,
355
- 3,
356
- 4,
357
- 5
358
- ].map(()=>TxHash.random()),
359
- txs: options.lastBlock.txs
360
- } : undefined;
361
- return CheckpointProposal.createProposalFromSigner(checkpointHeader, archiveRoot, feeAssetPriceModifier, lastBlockInfo, (payload)=>Promise.resolve(signer.signMessage(payload)));
350
+ inHash: checkpointHeader.inHash,
351
+ archiveRoot,
352
+ txHashes: options.lastBlock.txHashes,
353
+ txs: options.lastBlock.txs,
354
+ signer
355
+ }) : undefined;
356
+ return CheckpointProposal.createProposalFromSigner(checkpointHeader, archiveRoot, feeAssetPriceModifier, lastBlockProposal, (payload)=>Promise.resolve(signer.signMessage(payload)));
362
357
  };
363
358
  /**
364
359
  * Create a checkpoint attestation for testing
@@ -33,5 +33,6 @@ export declare function calculateMaxBlocksPerSlot(aztecSlotDurationSec: number,
33
33
  checkpointAssembleTime?: number;
34
34
  p2pPropagationTime?: number;
35
35
  l1PublishingTime?: number;
36
+ pipelining?: boolean;
36
37
  }): number;
37
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90aW1ldGFibGUvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7R0FVRztBQUVILG1GQUFtRjtBQUNuRixlQUFPLE1BQU0sOEJBQThCLElBQUksQ0FBQztBQUVoRCx1RkFBdUY7QUFDdkYsZUFBTyxNQUFNLHdCQUF3QixJQUFJLENBQUM7QUFFMUMscUZBQXFGO0FBQ3JGLGVBQU8sTUFBTSw0QkFBNEIsSUFBSSxDQUFDO0FBRTlDLHdGQUF3RjtBQUN4RixlQUFPLE1BQU0sMEJBQTBCLEtBQUssQ0FBQztBQUU3Qyw2REFBNkQ7QUFDN0QsZUFBTyxNQUFNLGtCQUFrQixJQUFJLENBQUM7QUFFcEM7Ozs7Ozs7O0dBUUc7QUFDSCx3QkFBZ0IseUJBQXlCLENBQ3ZDLG9CQUFvQixFQUFFLE1BQU0sRUFDNUIsZ0JBQWdCLEVBQUUsTUFBTSxHQUFHLFNBQVMsRUFDcEMsSUFBSSxHQUFFO0lBQ0osNEJBQTRCLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDdEMsc0JBQXNCLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDaEMsa0JBQWtCLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDNUIsZ0JBQWdCLENBQUMsRUFBRSxNQUFNLENBQUM7Q0FDdEIsR0FDTCxNQUFNLENBb0JSIn0=
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90aW1ldGFibGUvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7R0FVRztBQUVILG1GQUFtRjtBQUNuRixlQUFPLE1BQU0sOEJBQThCLElBQUksQ0FBQztBQUVoRCx1RkFBdUY7QUFDdkYsZUFBTyxNQUFNLHdCQUF3QixJQUFJLENBQUM7QUFFMUMscUZBQXFGO0FBQ3JGLGVBQU8sTUFBTSw0QkFBNEIsSUFBSSxDQUFDO0FBRTlDLHdGQUF3RjtBQUN4RixlQUFPLE1BQU0sMEJBQTBCLEtBQUssQ0FBQztBQUU3Qyw2REFBNkQ7QUFDN0QsZUFBTyxNQUFNLGtCQUFrQixJQUFJLENBQUM7QUFFcEM7Ozs7Ozs7O0dBUUc7QUFDSCx3QkFBZ0IseUJBQXlCLENBQ3ZDLG9CQUFvQixFQUFFLE1BQU0sRUFDNUIsZ0JBQWdCLEVBQUUsTUFBTSxHQUFHLFNBQVMsRUFDcEMsSUFBSSxHQUFFO0lBQ0osNEJBQTRCLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDdEMsc0JBQXNCLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDaEMsa0JBQWtCLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDNUIsZ0JBQWdCLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDMUIsVUFBVSxDQUFDLEVBQUUsT0FBTyxDQUFDO0NBQ2pCLEdBQ0wsTUFBTSxDQXdCUiJ9
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/timetable/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,mFAAmF;AACnF,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAEhD,uFAAuF;AACvF,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,qFAAqF;AACrF,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C,wFAAwF;AACxF,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,6DAA6D;AAC7D,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,oBAAoB,EAAE,MAAM,EAC5B,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,IAAI,GAAE;IACJ,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACtB,GACL,MAAM,CAoBR"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/timetable/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,mFAAmF;AACnF,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAEhD,uFAAuF;AACvF,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,qFAAqF;AACrF,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C,wFAAwF;AACxF,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,6DAA6D;AAC7D,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,oBAAoB,EAAE,MAAM,EAC5B,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,IAAI,GAAE;IACJ,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;CACjB,GACL,MAAM,CAwBR"}
@@ -31,8 +31,12 @@
31
31
  const l1Time = opts.l1PublishingTime ?? DEFAULT_L1_PUBLISHING_TIME;
32
32
  // Calculate checkpoint finalization time (assembly + round-trip propagation + L1 publishing)
33
33
  const checkpointFinalizationTime = assembleTime + p2pTime * 2 + l1Time;
34
- // Time reserved at end for last sub-slot (validator re-execution) + finalization
35
- const timeReservedAtEnd = blockDurationSec + checkpointFinalizationTime;
34
+ // When pipelining, finalization is deferred to the next slot, but we still reserve
35
+ // a sub-slot for validator re-execution so they can produce attestations.
36
+ let timeReservedAtEnd = blockDurationSec;
37
+ if (!opts.pipelining) {
38
+ timeReservedAtEnd += checkpointFinalizationTime;
39
+ }
36
40
  // Time available for building blocks
37
41
  const timeAvailableForBlocks = aztecSlotDurationSec - initOffset - timeReservedAtEnd;
38
42
  return Math.max(1, Math.floor(timeAvailableForBlocks / blockDurationSec));
@@ -0,0 +1,11 @@
1
+ import type { PublicDataTreeLeaf } from '../trees/index.js';
2
+ /** Data used to initialize the genesis block, including prefilled public state and an optional timestamp. */
3
+ export type GenesisData = {
4
+ /** Public data tree leaves to pre-populate in the genesis state (e.g. fee juice balances). */
5
+ prefilledPublicData: PublicDataTreeLeaf[];
6
+ /** Timestamp for the genesis block header. Defaults to 0 (canonical empty genesis) in production. */
7
+ genesisTimestamp: bigint;
8
+ };
9
+ /** An empty genesis data with no prefilled state and a zero timestamp. */
10
+ export declare const EMPTY_GENESIS_DATA: GenesisData;
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXNpc19kYXRhLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd29ybGQtc3RhdGUvZ2VuZXNpc19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFNUQsNkdBQTZHO0FBQzdHLE1BQU0sTUFBTSxXQUFXLEdBQUc7SUFDeEIsOEZBQThGO0lBQzlGLG1CQUFtQixFQUFFLGtCQUFrQixFQUFFLENBQUM7SUFDMUMscUdBQXFHO0lBQ3JHLGdCQUFnQixFQUFFLE1BQU0sQ0FBQztDQUMxQixDQUFDO0FBRUYsMEVBQTBFO0FBQzFFLGVBQU8sTUFBTSxrQkFBa0IsRUFBRSxXQUdoQyxDQUFDIn0=
@@ -0,0 +1 @@
1
+ {"version":3,"file":"genesis_data.d.ts","sourceRoot":"","sources":["../../src/world-state/genesis_data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,6GAA6G;AAC7G,MAAM,MAAM,WAAW,GAAG;IACxB,8FAA8F;IAC9F,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IAC1C,qGAAqG;IACrG,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,kBAAkB,EAAE,WAGhC,CAAC"}
@@ -0,0 +1,4 @@
1
+ /** An empty genesis data with no prefilled state and a zero timestamp. */ export const EMPTY_GENESIS_DATA = {
2
+ prefilledPublicData: [],
3
+ genesisTimestamp: 0n
4
+ };
@@ -1,2 +1,3 @@
1
+ export * from './genesis_data.js';
1
2
  export * from './world_state_revision.js';
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93b3JsZC1zdGF0ZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLDJCQUEyQixDQUFDIn0=
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93b3JsZC1zdGF0ZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLG1CQUFtQixDQUFDO0FBQ2xDLGNBQWMsMkJBQTJCLENBQUMifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/world-state/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/world-state/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC"}
@@ -1 +1,2 @@
1
+ export * from './genesis_data.js';
1
2
  export * from './world_state_revision.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/stdlib",
3
- "version": "5.0.0-nightly.20260409",
3
+ "version": "5.0.0-nightly.20260410",
4
4
  "type": "module",
5
5
  "inherits": [
6
6
  "../package.common.json",
@@ -92,13 +92,13 @@
92
92
  },
93
93
  "dependencies": {
94
94
  "@aws-sdk/client-s3": "^3.892.0",
95
- "@aztec/bb.js": "5.0.0-nightly.20260409",
96
- "@aztec/blob-lib": "5.0.0-nightly.20260409",
97
- "@aztec/constants": "5.0.0-nightly.20260409",
98
- "@aztec/ethereum": "5.0.0-nightly.20260409",
99
- "@aztec/foundation": "5.0.0-nightly.20260409",
100
- "@aztec/l1-artifacts": "5.0.0-nightly.20260409",
101
- "@aztec/noir-noirc_abi": "5.0.0-nightly.20260409",
95
+ "@aztec/bb.js": "5.0.0-nightly.20260410",
96
+ "@aztec/blob-lib": "5.0.0-nightly.20260410",
97
+ "@aztec/constants": "5.0.0-nightly.20260410",
98
+ "@aztec/ethereum": "5.0.0-nightly.20260410",
99
+ "@aztec/foundation": "5.0.0-nightly.20260410",
100
+ "@aztec/l1-artifacts": "5.0.0-nightly.20260410",
101
+ "@aztec/noir-noirc_abi": "5.0.0-nightly.20260410",
102
102
  "@google-cloud/storage": "^7.15.0",
103
103
  "axios": "^1.13.5",
104
104
  "json-stringify-deterministic": "1.0.12",
@@ -2,8 +2,9 @@ import { createSafeJsonRpcClient, defaultFetch } from '@aztec/foundation/json-rp
2
2
 
3
3
  import { z } from 'zod';
4
4
 
5
- import { type ApiSchemaFor, optional } from '../schemas/schemas.js';
6
- import { type Offense, OffenseSchema, type SlashPayloadRound, SlashPayloadRoundSchema } from '../slashing/index.js';
5
+ import type { ApiSchemaFor } from '../schemas/schemas.js';
6
+ import { optional } from '../schemas/schemas.js';
7
+ import { type Offense, OffenseSchema } from '../slashing/index.js';
7
8
  import { type ComponentsVersions, getVersioningResponseHandler } from '../versioning/index.js';
8
9
  import { type ArchiverSpecificConfig, ArchiverSpecificConfigSchema } from './archiver.js';
9
10
  import { type SequencerConfig, SequencerConfigSchema } from './configs.js';
@@ -46,9 +47,6 @@ export interface AztecNodeAdmin {
46
47
  /** Resumes archiver and world state syncing. */
47
48
  resumeSync(): Promise<void>;
48
49
 
49
- /** Returns all monitored payloads by the slasher for the current round. */
50
- getSlashPayloads(): Promise<SlashPayloadRound[]>;
51
-
52
50
  /** Returns all offenses applicable for the given round. */
53
51
  getSlashOffenses(round: bigint | 'all' | 'current'): Promise<Offense[]>;
54
52
 
@@ -104,7 +102,6 @@ export const AztecNodeAdminApiSchema: ApiSchemaFor<AztecNodeAdmin> = {
104
102
  rollbackTo: z.function().args(z.number(), optional(z.boolean()), optional(z.boolean())).returns(z.void()),
105
103
  pauseSync: z.function().returns(z.void()),
106
104
  resumeSync: z.function().returns(z.void()),
107
- getSlashPayloads: z.function().returns(z.array(SlashPayloadRoundSchema)),
108
105
  getSlashOffenses: z
109
106
  .function()
110
107
  .args(z.union([z.bigint(), z.literal('all'), z.literal('current')]))
@@ -3,12 +3,8 @@ import { schemas, zodFor } from '@aztec/foundation/schemas';
3
3
 
4
4
  import { z } from 'zod';
5
5
 
6
- export type SlasherClientType = 'empire' | 'tally';
7
-
8
6
  export interface SlasherConfig {
9
7
  slashOverridePayload?: EthAddress;
10
- slashMinPenaltyPercentage: number;
11
- slashMaxPenaltyPercentage: number;
12
8
  slashSelfAllowed?: boolean; // Whether to allow slashes to own validators
13
9
  slashValidatorsAlways: EthAddress[]; // Array of validator addresses
14
10
  slashValidatorsNever: EthAddress[]; // Array of validator addresses
@@ -32,8 +28,6 @@ export interface SlasherConfig {
32
28
  export const SlasherConfigSchema = zodFor<SlasherConfig>()(
33
29
  z.object({
34
30
  slashOverridePayload: schemas.EthAddress.optional(),
35
- slashMinPenaltyPercentage: z.number(),
36
- slashMaxPenaltyPercentage: z.number(),
37
31
  slashValidatorsAlways: z.array(schemas.EthAddress),
38
32
  slashValidatorsNever: z.array(schemas.EthAddress),
39
33
  slashPrunePenalty: schemas.BigInt,
@@ -9,7 +9,6 @@ import type {
9
9
  BlockProposal,
10
10
  BlockProposalOptions,
11
11
  CheckpointAttestation,
12
- CheckpointLastBlockData,
13
12
  CheckpointProposal,
14
13
  CheckpointProposalOptions,
15
14
  } from '@aztec/stdlib/p2p';
@@ -118,8 +117,6 @@ export const ValidatorClientFullConfigSchema = zodFor<Omit<ValidatorClientFullCo
118
117
  }),
119
118
  );
120
119
 
121
- export type CreateCheckpointProposalLastBlockData = Omit<CheckpointLastBlockData, 'txHashes'> & { txs: Tx[] };
122
-
123
120
  export interface Validator {
124
121
  start(): Promise<void>;
125
122
  updateConfig(config: Partial<ValidatorClientFullConfig>): void;
@@ -140,7 +137,7 @@ export interface Validator {
140
137
  checkpointHeader: CheckpointHeader,
141
138
  archive: Fr,
142
139
  feeAssetPriceModifier: bigint,
143
- lastBlockInfo: CreateCheckpointProposalLastBlockData | undefined,
140
+ lastBlockProposal: BlockProposal | undefined,
144
141
  proposerAddress: EthAddress | undefined,
145
142
  options: CheckpointProposalOptions,
146
143
  ): Promise<CheckpointProposal>;
@@ -1 +1 @@
1
- export * from './slash_factory.js';
1
+ // No exports.
@@ -161,7 +161,7 @@ export class CheckpointProposal extends Gossipable {
161
161
  checkpointHeader: CheckpointHeader,
162
162
  archiveRoot: Fr,
163
163
  feeAssetPriceModifier: bigint,
164
- lastBlockInfo: CheckpointLastBlockData | undefined,
164
+ lastBlockProposal: BlockProposal | undefined,
165
165
  payloadSigner: (payload: Buffer32, context: SigningContext) => Promise<Signature>,
166
166
  ): Promise<CheckpointProposal> {
167
167
  // Sign the checkpoint payload with CHECKPOINT_PROPOSAL duty type
@@ -175,35 +175,19 @@ export class CheckpointProposal extends Gossipable {
175
175
 
176
176
  const checkpointContext: SigningContext = {
177
177
  slot: checkpointHeader.slotNumber,
178
- blockNumber: lastBlockInfo?.blockHeader?.globalVariables.blockNumber ?? BlockNumber(0),
178
+ blockNumber: lastBlockProposal?.blockNumber ?? BlockNumber(0),
179
179
  dutyType: DutyType.CHECKPOINT_PROPOSAL,
180
180
  };
181
181
 
182
- if (lastBlockInfo) {
183
- // Sign block proposal before signing checkpoint proposal to ensure HA protection
184
- const lastBlockProposal = await BlockProposal.createProposalFromSigner(
185
- lastBlockInfo.blockHeader,
186
- lastBlockInfo.indexWithinCheckpoint,
187
- checkpointHeader.inHash,
188
- archiveRoot,
189
- lastBlockInfo.txHashes,
190
- lastBlockInfo.txs,
191
- payloadSigner,
192
- );
193
-
194
- const checkpointSignature = await payloadSigner(checkpointHash, checkpointContext);
195
-
196
- return new CheckpointProposal(checkpointHeader, archiveRoot, feeAssetPriceModifier, checkpointSignature, {
197
- blockHeader: lastBlockInfo.blockHeader,
198
- indexWithinCheckpoint: lastBlockInfo.indexWithinCheckpoint,
199
- txHashes: lastBlockInfo.txHashes,
200
- signature: lastBlockProposal.signature,
201
- signedTxs: lastBlockProposal.signedTxs,
202
- });
203
- }
204
-
205
182
  const checkpointSignature = await payloadSigner(checkpointHash, checkpointContext);
206
- return new CheckpointProposal(checkpointHeader, archiveRoot, feeAssetPriceModifier, checkpointSignature);
183
+
184
+ return new CheckpointProposal(
185
+ checkpointHeader,
186
+ archiveRoot,
187
+ feeAssetPriceModifier,
188
+ checkpointSignature,
189
+ lastBlockProposal,
190
+ );
207
191
  }
208
192
 
209
193
  /**
@@ -1,6 +1,5 @@
1
1
  export * from './types.js';
2
2
  export * from './interfaces.js';
3
3
  export * from './helpers.js';
4
- export * from './empire.js';
5
- export * from './tally.js';
4
+ export * from './votes.js';
6
5
  export * from './serialization.js';
@@ -1,15 +1,7 @@
1
- import { times } from '@aztec/foundation/collection';
2
1
  import { EthAddress } from '@aztec/foundation/eth-address';
3
2
  import { BufferReader, bigintToUInt64BE, bigintToUInt128BE, serializeToBuffer } from '@aztec/foundation/serialize';
4
3
 
5
- import type {
6
- Offense,
7
- OffenseType,
8
- SlashPayload,
9
- SlashPayloadRound,
10
- ValidatorSlash,
11
- ValidatorSlashOffense,
12
- } from './types.js';
4
+ import type { Offense, OffenseType } from './types.js';
13
5
 
14
6
  export function serializeOffense(offense: Offense): Buffer {
15
7
  return serializeToBuffer(
@@ -29,75 +21,3 @@ export function deserializeOffense(buffer: Buffer): Offense {
29
21
 
30
22
  return { validator, amount, offenseType: offense, epochOrSlot };
31
23
  }
32
-
33
- function serializeValidatorSlashOffense(offense: ValidatorSlashOffense): Buffer {
34
- return serializeToBuffer(bigintToUInt64BE(offense.epochOrSlot), offense.offenseType);
35
- }
36
-
37
- function deserializeValidatorSlashOffense(buffer: Buffer | BufferReader): ValidatorSlashOffense {
38
- const reader = BufferReader.asReader(buffer);
39
- return {
40
- epochOrSlot: reader.readUInt64(),
41
- offenseType: reader.readNumber() as OffenseType,
42
- };
43
- }
44
-
45
- function serializeValidatorSlash(slash: ValidatorSlash): Buffer {
46
- return serializeToBuffer(
47
- slash.validator,
48
- bigintToUInt128BE(slash.amount),
49
- slash.offenses.length,
50
- slash.offenses.map(serializeValidatorSlashOffense),
51
- );
52
- }
53
-
54
- function deserializeValidatorSlash(buffer: Buffer | BufferReader): ValidatorSlash {
55
- const reader = BufferReader.asReader(buffer);
56
- const validator = reader.readObject(EthAddress);
57
- const amount = reader.readUInt128();
58
- const offensesCount = reader.readNumber();
59
- const offenses = times(offensesCount, () => deserializeValidatorSlashOffense(reader));
60
-
61
- return { validator, amount, offenses };
62
- }
63
-
64
- export function serializeSlashPayload(payload: SlashPayload): Buffer {
65
- return serializeToBuffer(
66
- payload.address,
67
- payload.slashes.length,
68
- payload.slashes.map(serializeValidatorSlash),
69
- bigintToUInt64BE(payload.timestamp),
70
- );
71
- }
72
-
73
- export function deserializeSlashPayload(buffer: Buffer): SlashPayload {
74
- const reader = BufferReader.asReader(buffer);
75
- const address = reader.readObject(EthAddress);
76
- const slashesCount = reader.readNumber();
77
- const slashes = times(slashesCount, () => deserializeValidatorSlash(reader));
78
- const timestamp = reader.readUInt64();
79
- return { address, slashes, timestamp };
80
- }
81
-
82
- export function serializeSlashPayloadRound(payload: SlashPayloadRound): Buffer {
83
- return serializeToBuffer(
84
- payload.address,
85
- payload.slashes.length,
86
- payload.slashes.map(serializeValidatorSlash),
87
- bigintToUInt64BE(payload.timestamp),
88
- Number(payload.votes),
89
- bigintToUInt64BE(payload.round),
90
- );
91
- }
92
-
93
- export function deserializeSlashPayloadRound(buffer: Buffer): SlashPayloadRound {
94
- const reader = BufferReader.asReader(buffer);
95
- const address = reader.readObject(EthAddress);
96
- const slashesCount = reader.readNumber();
97
- const slashes = times(slashesCount, () => deserializeValidatorSlash(reader));
98
- const timestamp = reader.readUInt64();
99
- const votes = BigInt(reader.readNumber());
100
- const round = reader.readUInt64();
101
-
102
- return { address, slashes, timestamp, votes, round };
103
- }
@@ -126,45 +126,13 @@ export type ValidatorSlash = {
126
126
  offenses: ValidatorSlashOffense[];
127
127
  };
128
128
 
129
- /** Slash payload as published by the empire slash proposer */
130
- export type SlashPayload = {
131
- address: EthAddress;
132
- slashes: ValidatorSlash[];
133
- timestamp: bigint;
134
- };
135
-
136
- /** Slash payload with round information from empire slash proposer */
137
- export type SlashPayloadRound = SlashPayload & { votes: bigint; round: bigint };
138
-
139
- export const SlashPayloadRoundSchema = zodFor<SlashPayloadRound>()(
140
- z.object({
141
- address: schemas.EthAddress,
142
- timestamp: schemas.BigInt,
143
- votes: schemas.BigInt,
144
- round: schemas.BigInt,
145
- slashes: z.array(
146
- z.object({
147
- validator: schemas.EthAddress,
148
- amount: schemas.BigInt,
149
- offenses: z.array(z.object({ offenseType: OffenseTypeSchema, epochOrSlot: schemas.BigInt })),
150
- }),
151
- ),
152
- }),
153
- );
154
-
155
- /** Votes for a validator slash in the consensus slash proposer */
129
+ /** Votes for a validator slash in the slashing proposer */
156
130
  export type ValidatorSlashVote = number;
157
131
 
158
132
  export type ProposerSlashAction =
159
- /** Create a new slash payload on an empire-based slash proposer */
160
- | { type: 'create-empire-payload'; data: ValidatorSlash[] }
161
- /** Vote for a slashing payload on an empire-based slash proposer */
162
- | { type: 'vote-empire-payload'; payload: EthAddress }
163
- /** Execute a slashing payload on an empire-based slash proposer */
164
- | { type: 'execute-empire-payload'; round: bigint }
165
- /** Vote for offenses on a consensus slashing proposer */
133
+ /** Vote for offenses on the slashing proposer */
166
134
  | { type: 'vote-offenses'; votes: ValidatorSlashVote[]; committees: EthAddress[][]; round: bigint }
167
- /** Execute a slashing round on a consensus slashing proposer */
135
+ /** Execute a slashing round on the slashing proposer */
168
136
  | { type: 'execute-slash'; committees: EthAddress[][]; round: bigint };
169
137
 
170
138
  export type ProposerSlashActionType = ProposerSlashAction['type'];
@@ -28,7 +28,7 @@ export function getSlashConsensusVotesFromOffenses(
28
28
  targetCommitteeSize: number;
29
29
  maxSlashedValidators?: number;
30
30
  },
31
- logger: Logger = createLogger('slasher:tally'),
31
+ logger: Logger = createLogger('slasher:votes'),
32
32
  ): ValidatorSlashVote[] {
33
33
  const { slashingAmounts, targetCommitteeSize, maxSlashedValidators } = settings;
34
34
 
@@ -596,28 +596,30 @@ export const makeBlockProposal = (options?: MakeBlockProposalOptions): Promise<B
596
596
  );
597
597
  };
598
598
 
599
- export const makeCheckpointProposal = (options?: MakeCheckpointProposalOptions): Promise<CheckpointProposal> => {
600
- const blockHeader = options?.lastBlock?.blockHeader ?? makeBlockHeader(1);
599
+ export const makeCheckpointProposal = async (options?: MakeCheckpointProposalOptions): Promise<CheckpointProposal> => {
601
600
  const checkpointHeader = options?.checkpointHeader ?? makeCheckpointHeader(1);
602
601
  const archiveRoot = options?.archiveRoot ?? Fr.random();
603
602
  const feeAssetPriceModifier = options?.feeAssetPriceModifier ?? 0n;
604
603
  const signer = options?.signer ?? Secp256k1Signer.random();
605
604
 
606
- // Build lastBlock info if provided
607
- const lastBlockInfo = options?.lastBlock
608
- ? {
609
- blockHeader,
610
- indexWithinCheckpoint: options.lastBlock.indexWithinCheckpoint ?? IndexWithinCheckpoint(4), // Last block in a 5-block checkpoint
611
- txHashes: options.lastBlock.txHashes ?? [0, 1, 2, 3, 4, 5].map(() => TxHash.random()),
605
+ // Build a signed block proposal if lastBlock options are provided
606
+ const lastBlockProposal = options?.lastBlock
607
+ ? await makeBlockProposal({
608
+ blockHeader: options.lastBlock.blockHeader,
609
+ indexWithinCheckpoint: options.lastBlock.indexWithinCheckpoint ?? IndexWithinCheckpoint(4),
610
+ inHash: checkpointHeader.inHash,
611
+ archiveRoot,
612
+ txHashes: options.lastBlock.txHashes,
612
613
  txs: options.lastBlock.txs,
613
- }
614
+ signer,
615
+ })
614
616
  : undefined;
615
617
 
616
618
  return CheckpointProposal.createProposalFromSigner(
617
619
  checkpointHeader,
618
620
  archiveRoot,
619
621
  feeAssetPriceModifier,
620
- lastBlockInfo,
622
+ lastBlockProposal,
621
623
  payload => Promise.resolve(signer.signMessage(payload)),
622
624
  );
623
625
  };
@@ -42,6 +42,7 @@ export function calculateMaxBlocksPerSlot(
42
42
  checkpointAssembleTime?: number;
43
43
  p2pPropagationTime?: number;
44
44
  l1PublishingTime?: number;
45
+ pipelining?: boolean;
45
46
  } = {},
46
47
  ): number {
47
48
  if (!blockDurationSec) {
@@ -56,8 +57,12 @@ export function calculateMaxBlocksPerSlot(
56
57
  // Calculate checkpoint finalization time (assembly + round-trip propagation + L1 publishing)
57
58
  const checkpointFinalizationTime = assembleTime + p2pTime * 2 + l1Time;
58
59
 
59
- // Time reserved at end for last sub-slot (validator re-execution) + finalization
60
- const timeReservedAtEnd = blockDurationSec + checkpointFinalizationTime;
60
+ // When pipelining, finalization is deferred to the next slot, but we still reserve
61
+ // a sub-slot for validator re-execution so they can produce attestations.
62
+ let timeReservedAtEnd = blockDurationSec;
63
+ if (!opts.pipelining) {
64
+ timeReservedAtEnd += checkpointFinalizationTime;
65
+ }
61
66
 
62
67
  // Time available for building blocks
63
68
  const timeAvailableForBlocks = aztecSlotDurationSec - initOffset - timeReservedAtEnd;
@@ -0,0 +1,15 @@
1
+ import type { PublicDataTreeLeaf } from '../trees/index.js';
2
+
3
+ /** Data used to initialize the genesis block, including prefilled public state and an optional timestamp. */
4
+ export type GenesisData = {
5
+ /** Public data tree leaves to pre-populate in the genesis state (e.g. fee juice balances). */
6
+ prefilledPublicData: PublicDataTreeLeaf[];
7
+ /** Timestamp for the genesis block header. Defaults to 0 (canonical empty genesis) in production. */
8
+ genesisTimestamp: bigint;
9
+ };
10
+
11
+ /** An empty genesis data with no prefilled state and a zero timestamp. */
12
+ export const EMPTY_GENESIS_DATA: GenesisData = {
13
+ prefilledPublicData: [],
14
+ genesisTimestamp: 0n,
15
+ };
@@ -1 +1,2 @@
1
+ export * from './genesis_data.js';
1
2
  export * from './world_state_revision.js';
@@ -1,45 +0,0 @@
1
- import type { L1TxRequest } from '@aztec/ethereum/l1-tx-utils';
2
- import type { ViemClient } from '@aztec/ethereum/types';
3
- import { EthAddress } from '@aztec/foundation/eth-address';
4
- import { type Hex, type Log } from 'viem';
5
- import type { L1RollupConstants } from '../epoch-helpers/index.js';
6
- import { type SlashPayload, type ValidatorSlash, type ValidatorSlashOffense } from '../slashing/index.js';
7
- export declare class SlashFactoryContract {
8
- readonly client: ViemClient;
9
- private readonly logger;
10
- private readonly contract;
11
- constructor(client: ViemClient, address: Hex | EthAddress);
12
- get address(): EthAddress;
13
- buildCreatePayloadRequest(slashes: ValidatorSlash[]): L1TxRequest;
14
- /** Tries to extract a SlashPayloadCreated event from the given logs. */
15
- tryExtractSlashPayloadCreatedEvent(logs: Log[]): {
16
- eventName: "SlashPayloadCreated";
17
- args: {
18
- amounts: readonly bigint[];
19
- offenses: readonly (readonly bigint[])[];
20
- payloadAddress: `0x${string}`;
21
- validators: readonly `0x${string}`[];
22
- };
23
- } | undefined;
24
- getSlashPayloadCreatedEvents(): Promise<SlashPayload[]>;
25
- /**
26
- * Searches for a slash payload in the events emitted by the contract.
27
- * This method cannot query for historical payload events, it queries for payloads that have not yet expired.
28
- * @param payloadAddress The address of the payload to search for.
29
- * @param constants The L1 rollup constants needed for time calculations.
30
- */
31
- getSlashPayloadFromEvents(payloadAddress: EthAddress, settings: {
32
- logsBatchSize?: number;
33
- slashingRoundSize: number;
34
- slashingPayloadLifetimeInRounds: number;
35
- } & Pick<L1RollupConstants, 'slotDuration' | 'ethereumSlotDuration'>): Promise<Omit<SlashPayload, 'votes'> | undefined>;
36
- getAddressAndIsDeployed(slashes: ValidatorSlash[]): Promise<{
37
- address: EthAddress;
38
- salt: Hex;
39
- isDeployed: boolean;
40
- }>;
41
- private sortSlashes;
42
- }
43
- export declare function packValidatorSlashOffense(offense: ValidatorSlashOffense): bigint;
44
- export declare function unpackValidatorSlashOffense(packed: bigint): ValidatorSlashOffense;
45
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hfZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2wxLWNvbnRyYWN0cy9zbGFzaF9mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQy9ELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBR3hELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUkzRCxPQUFPLEVBQThCLEtBQUssR0FBRyxFQUFFLEtBQUssR0FBRyxFQUFtQyxNQUFNLE1BQU0sQ0FBQztBQUV2RyxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ25FLE9BQU8sRUFFTCxLQUFLLFlBQVksRUFDakIsS0FBSyxjQUFjLEVBQ25CLEtBQUsscUJBQXFCLEVBRTNCLE1BQU0sc0JBQXNCLENBQUM7QUFFOUIscUJBQWEsb0JBQW9CO2FBS2IsTUFBTSxFQUFFLFVBQVU7SUFKcEMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQTJDO0lBQ2xFLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUE0RDtJQUVyRixZQUNrQixNQUFNLEVBQUUsVUFBVSxFQUNsQyxPQUFPLEVBQUUsR0FBRyxHQUFHLFVBQVUsRUFPMUI7SUFFRCxJQUFXLE9BQU8sZUFFakI7SUFFTSx5QkFBeUIsQ0FBQyxPQUFPLEVBQUUsY0FBYyxFQUFFLEdBQUcsV0FBVyxDQWdCdkU7SUFFRCx3RUFBd0U7SUFDakUsa0NBQWtDLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRTs7Ozs7Ozs7a0JBRXBEO0lBRVksNEJBQTRCLElBQUksT0FBTyxDQUFDLFlBQVksRUFBRSxDQUFDLENBZW5FO0lBRUQ7Ozs7O09BS0c7SUFDVSx5QkFBeUIsQ0FDcEMsY0FBYyxFQUFFLFVBQVUsRUFDMUIsUUFBUSxFQUFFO1FBQ1IsYUFBYSxDQUFDLEVBQUUsTUFBTSxDQUFDO1FBQ3ZCLGlCQUFpQixFQUFFLE1BQU0sQ0FBQztRQUMxQiwrQkFBK0IsRUFBRSxNQUFNLENBQUM7S0FDekMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsY0FBYyxHQUFHLHNCQUFzQixDQUFDLEdBQ25FLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQW1EbEQ7SUFFWSx1QkFBdUIsQ0FDbEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxHQUN4QixPQUFPLENBQUM7UUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDO1FBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQztRQUFDLFVBQVUsRUFBRSxPQUFPLENBQUE7S0FBRSxDQUFDLENBUWxFO0lBRUQsT0FBTyxDQUFDLFdBQVc7Q0FRcEI7QUFFRCx3QkFBZ0IseUJBQXlCLENBQUMsT0FBTyxFQUFFLHFCQUFxQixHQUFHLE1BQU0sQ0FNaEY7QUFFRCx3QkFBZ0IsMkJBQTJCLENBQUMsTUFBTSxFQUFFLE1BQU0sR0FBRyxxQkFBcUIsQ0FLakYifQ==
@@ -1 +0,0 @@
1
- {"version":3,"file":"slash_factory.d.ts","sourceRoot":"","sources":["../../src/l1-contracts/slash_factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAI3D,OAAO,EAA8B,KAAK,GAAG,EAAE,KAAK,GAAG,EAAmC,MAAM,MAAM,CAAC;AAEvG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAE3B,MAAM,sBAAsB,CAAC;AAE9B,qBAAa,oBAAoB;aAKb,MAAM,EAAE,UAAU;IAJpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2C;IAClE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4D;IAErF,YACkB,MAAM,EAAE,UAAU,EAClC,OAAO,EAAE,GAAG,GAAG,UAAU,EAO1B;IAED,IAAW,OAAO,eAEjB;IAEM,yBAAyB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,WAAW,CAgBvE;IAED,wEAAwE;IACjE,kCAAkC,CAAC,IAAI,EAAE,GAAG,EAAE;;;;;;;;kBAEpD;IAEY,4BAA4B,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAenE;IAED;;;;;OAKG;IACU,yBAAyB,CACpC,cAAc,EAAE,UAAU,EAC1B,QAAQ,EAAE;QACR,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,+BAA+B,EAAE,MAAM,CAAC;KACzC,GAAG,IAAI,CAAC,iBAAiB,EAAE,cAAc,GAAG,sBAAsB,CAAC,GACnE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAmDlD;IAEY,uBAAuB,CAClC,OAAO,EAAE,cAAc,EAAE,GACxB,OAAO,CAAC;QAAE,OAAO,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,GAAG,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC,CAQlE;IAED,OAAO,CAAC,WAAW;CAQpB;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAMhF;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,qBAAqB,CAKjF"}