@aztec/aztec-node 0.0.1-commit.24de95ac → 0.0.1-commit.2606882
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/aztec-node/block_response_helpers.d.ts +25 -0
- package/dest/aztec-node/block_response_helpers.d.ts.map +1 -0
- package/dest/aztec-node/block_response_helpers.js +112 -0
- package/dest/aztec-node/config.d.ts +17 -8
- package/dest/aztec-node/config.d.ts.map +1 -1
- package/dest/aztec-node/config.js +22 -8
- package/dest/aztec-node/node_metrics.d.ts +1 -1
- package/dest/aztec-node/node_metrics.d.ts.map +1 -1
- package/dest/aztec-node/node_metrics.js +9 -16
- package/dest/aztec-node/public_data_overrides.d.ts +13 -0
- package/dest/aztec-node/public_data_overrides.d.ts.map +1 -0
- package/dest/aztec-node/public_data_overrides.js +21 -0
- package/dest/aztec-node/server.d.ts +109 -199
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +1602 -506
- package/dest/bin/index.d.ts +1 -1
- package/dest/index.d.ts +1 -1
- package/dest/sentinel/config.d.ts +3 -2
- package/dest/sentinel/config.d.ts.map +1 -1
- package/dest/sentinel/config.js +15 -5
- package/dest/sentinel/factory.d.ts +5 -3
- package/dest/sentinel/factory.d.ts.map +1 -1
- package/dest/sentinel/factory.js +5 -5
- package/dest/sentinel/index.d.ts +1 -1
- package/dest/sentinel/sentinel.d.ts +151 -25
- package/dest/sentinel/sentinel.d.ts.map +1 -1
- package/dest/sentinel/sentinel.js +290 -110
- package/dest/sentinel/store.d.ts +11 -10
- package/dest/sentinel/store.d.ts.map +1 -1
- package/dest/sentinel/store.js +36 -23
- package/dest/test/index.d.ts +3 -3
- package/dest/test/index.d.ts.map +1 -1
- package/package.json +31 -28
- package/src/aztec-node/block_response_helpers.ts +161 -0
- package/src/aztec-node/config.ts +45 -21
- package/src/aztec-node/node_metrics.ts +6 -17
- package/src/aztec-node/public_data_overrides.ts +35 -0
- package/src/aztec-node/server.ts +1385 -640
- package/src/sentinel/README.md +103 -0
- package/src/sentinel/config.ts +18 -6
- package/src/sentinel/factory.ts +9 -11
- package/src/sentinel/sentinel.ts +375 -136
- package/src/sentinel/store.ts +43 -34
- package/src/test/index.ts +2 -2
package/dest/sentinel/store.js
CHANGED
|
@@ -1,30 +1,31 @@
|
|
|
1
|
+
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
2
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
3
|
import { BufferReader, numToUInt8, numToUInt32BE, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
3
4
|
export class SentinelStore {
|
|
4
5
|
store;
|
|
5
6
|
config;
|
|
6
|
-
static SCHEMA_VERSION =
|
|
7
|
+
static SCHEMA_VERSION = 4;
|
|
7
8
|
// a map from validator address to their ValidatorStatusHistory
|
|
8
9
|
historyMap;
|
|
9
|
-
// a map from validator address to their historical
|
|
10
|
+
// a map from validator address to their historical epoch performance, evaluated at end-of-epoch.
|
|
10
11
|
// e.g. { validator: [{ epoch: 1, missed: 1, total: 10 }, { epoch: 2, missed: 3, total: 7 }, ...] }
|
|
11
|
-
|
|
12
|
+
epochMap;
|
|
12
13
|
constructor(store, config){
|
|
13
14
|
this.store = store;
|
|
14
15
|
this.config = config;
|
|
15
16
|
this.historyMap = store.openMap('sentinel-validator-status');
|
|
16
|
-
this.
|
|
17
|
+
this.epochMap = store.openMap('sentinel-validator-epoch');
|
|
17
18
|
}
|
|
18
19
|
getHistoryLength() {
|
|
19
20
|
return this.config.historyLength;
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
-
return this.config.
|
|
22
|
+
getHistoricEpochPerformanceLength() {
|
|
23
|
+
return this.config.historicEpochPerformanceLength;
|
|
23
24
|
}
|
|
24
|
-
async
|
|
25
|
+
async updateEpochPerformance(epoch, performance) {
|
|
25
26
|
await this.store.transactionAsync(async ()=>{
|
|
26
27
|
for (const [who, { missed, total }] of Object.entries(performance)){
|
|
27
|
-
await this.
|
|
28
|
+
await this.pushValidatorEpochPerformance({
|
|
28
29
|
who: EthAddress.fromString(who),
|
|
29
30
|
missed,
|
|
30
31
|
total,
|
|
@@ -33,12 +34,12 @@ export class SentinelStore {
|
|
|
33
34
|
}
|
|
34
35
|
});
|
|
35
36
|
}
|
|
36
|
-
async
|
|
37
|
-
const currentPerformanceBuffer = await this.
|
|
37
|
+
async getEpochPerformance(who) {
|
|
38
|
+
const currentPerformanceBuffer = await this.epochMap.getAsync(who.toString());
|
|
38
39
|
return currentPerformanceBuffer ? this.deserializePerformance(currentPerformanceBuffer) : [];
|
|
39
40
|
}
|
|
40
|
-
async
|
|
41
|
-
const currentPerformance = await this.
|
|
41
|
+
async pushValidatorEpochPerformance({ who, missed, total, epoch }) {
|
|
42
|
+
const currentPerformance = await this.getEpochPerformance(who);
|
|
42
43
|
const existingIndex = currentPerformance.findIndex((p)=>p.epoch === epoch);
|
|
43
44
|
if (existingIndex !== -1) {
|
|
44
45
|
currentPerformance[existingIndex] = {
|
|
@@ -56,9 +57,9 @@ export class SentinelStore {
|
|
|
56
57
|
// This should be sorted by epoch, but just in case.
|
|
57
58
|
// Since we keep the size small, this is not a big deal.
|
|
58
59
|
currentPerformance.sort((a, b)=>Number(a.epoch - b.epoch));
|
|
59
|
-
// keep the most recent `
|
|
60
|
-
const performanceToKeep = currentPerformance.slice(-this.config.
|
|
61
|
-
await this.
|
|
60
|
+
// keep the most recent `historicEpochPerformanceLength` entries.
|
|
61
|
+
const performanceToKeep = currentPerformance.slice(-this.config.historicEpochPerformanceLength);
|
|
62
|
+
await this.epochMap.set(who.toString(), this.serializePerformance(performanceToKeep));
|
|
62
63
|
}
|
|
63
64
|
async updateValidators(slot, statuses) {
|
|
64
65
|
await this.store.transactionAsync(async ()=>{
|
|
@@ -105,7 +106,7 @@ export class SentinelStore {
|
|
|
105
106
|
const performance = [];
|
|
106
107
|
while(!reader.isEmpty()){
|
|
107
108
|
performance.push({
|
|
108
|
-
epoch:
|
|
109
|
+
epoch: EpochNumber(reader.readNumber()),
|
|
109
110
|
missed: reader.readNumber(),
|
|
110
111
|
total: reader.readNumber()
|
|
111
112
|
});
|
|
@@ -122,7 +123,7 @@ export class SentinelStore {
|
|
|
122
123
|
const reader = new BufferReader(buffer);
|
|
123
124
|
const history = [];
|
|
124
125
|
while(!reader.isEmpty()){
|
|
125
|
-
const slot =
|
|
126
|
+
const slot = SlotNumber(reader.readNumber());
|
|
126
127
|
const status = this.statusFromNumber(reader.readUInt8());
|
|
127
128
|
history.push({
|
|
128
129
|
slot,
|
|
@@ -133,16 +134,22 @@ export class SentinelStore {
|
|
|
133
134
|
}
|
|
134
135
|
statusToNumber(status) {
|
|
135
136
|
switch(status){
|
|
136
|
-
case '
|
|
137
|
+
case 'checkpoint-mined':
|
|
137
138
|
return 1;
|
|
138
|
-
case '
|
|
139
|
+
case 'checkpoint-valid':
|
|
139
140
|
return 2;
|
|
140
|
-
case '
|
|
141
|
+
case 'checkpoint-missed':
|
|
141
142
|
return 3;
|
|
142
143
|
case 'attestation-sent':
|
|
143
144
|
return 4;
|
|
144
145
|
case 'attestation-missed':
|
|
145
146
|
return 5;
|
|
147
|
+
case 'blocks-missed':
|
|
148
|
+
return 6;
|
|
149
|
+
case 'checkpoint-invalid':
|
|
150
|
+
return 7;
|
|
151
|
+
case 'checkpoint-unvalidated':
|
|
152
|
+
return 8;
|
|
146
153
|
default:
|
|
147
154
|
{
|
|
148
155
|
const _exhaustive = status;
|
|
@@ -153,15 +160,21 @@ export class SentinelStore {
|
|
|
153
160
|
statusFromNumber(status) {
|
|
154
161
|
switch(status){
|
|
155
162
|
case 1:
|
|
156
|
-
return '
|
|
163
|
+
return 'checkpoint-mined';
|
|
157
164
|
case 2:
|
|
158
|
-
return '
|
|
165
|
+
return 'checkpoint-valid';
|
|
159
166
|
case 3:
|
|
160
|
-
return '
|
|
167
|
+
return 'checkpoint-missed';
|
|
161
168
|
case 4:
|
|
162
169
|
return 'attestation-sent';
|
|
163
170
|
case 5:
|
|
164
171
|
return 'attestation-missed';
|
|
172
|
+
case 6:
|
|
173
|
+
return 'blocks-missed';
|
|
174
|
+
case 7:
|
|
175
|
+
return 'checkpoint-invalid';
|
|
176
|
+
case 8:
|
|
177
|
+
return 'checkpoint-unvalidated';
|
|
165
178
|
default:
|
|
166
179
|
throw new Error(`Unknown status: ${status}`);
|
|
167
180
|
}
|
package/dest/test/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
2
|
import type { P2P } from '@aztec/p2p';
|
|
3
3
|
import { SequencerClient } from '@aztec/sequencer-client';
|
|
4
|
-
import {
|
|
4
|
+
import { DataWithholdingWatcher, type SlasherClientInterface } from '@aztec/slasher';
|
|
5
5
|
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
6
6
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
7
7
|
import type { L2LogsSource, Service, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
@@ -21,11 +21,11 @@ export declare class TestAztecNodeService extends AztecNodeService {
|
|
|
21
21
|
sequencer: SequencerClient | undefined;
|
|
22
22
|
slasherClient: SlasherClientInterface | undefined;
|
|
23
23
|
validatorsSentinel: Sentinel | undefined;
|
|
24
|
-
|
|
24
|
+
dataWithholdingWatcher: DataWithholdingWatcher | undefined;
|
|
25
25
|
l1ChainId: number;
|
|
26
26
|
version: number;
|
|
27
27
|
globalVariableBuilder: GlobalVariableBuilderInterface;
|
|
28
28
|
epochCache: EpochCacheInterface;
|
|
29
29
|
packageVersion: string;
|
|
30
30
|
}
|
|
31
|
-
//# sourceMappingURL=
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUQsT0FBTyxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsS0FBSyxzQkFBc0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JGLE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakUsT0FBTyxLQUFLLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3JHLE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbkUsT0FBTyxLQUFLLEVBQUUscUJBQXFCLElBQUksOEJBQThCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUVoRyxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFbkQsTUFBTSxDQUFDLE9BQU8sT0FBTyxvQkFBcUIsU0FBUSxnQkFBZ0I7SUFDakQsTUFBTSxFQUFFLGVBQWUsQ0FBQztJQUN4QixTQUFTLEVBQUUsR0FBRyxDQUFDO0lBQ2YsV0FBVyxFQUFFLGFBQWEsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDOUMsVUFBVSxFQUFFLFlBQVksQ0FBQztJQUN6QixrQkFBa0IsRUFBRSxrQkFBa0IsQ0FBQztJQUN2QyxtQkFBbUIsRUFBRSxtQkFBbUIsQ0FBQztJQUN6QyxzQkFBc0IsRUFBRSxzQkFBc0IsQ0FBQztJQUMvQyxTQUFTLEVBQUUsZUFBZSxHQUFHLFNBQVMsQ0FBQztJQUN2QyxhQUFhLEVBQUUsc0JBQXNCLEdBQUcsU0FBUyxDQUFDO0lBQ2xELGtCQUFrQixFQUFFLFFBQVEsR0FBRyxTQUFTLENBQUM7SUFDekMsc0JBQXNCLEVBQUUsc0JBQXNCLEdBQUcsU0FBUyxDQUFDO0lBQzNELFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsT0FBTyxFQUFFLE1BQU0sQ0FBQztJQUNoQixxQkFBcUIsRUFBRSw4QkFBOEIsQ0FBQztJQUN0RCxVQUFVLEVBQUUsbUJBQW1CLENBQUM7SUFDaEMsY0FBYyxFQUFFLE1BQU0sQ0FBQztDQUN2QyJ9
|
package/dest/test/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,KAAK,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACrG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,qBAAqB,IAAI,8BAA8B,EAAE,MAAM,kBAAkB,CAAC;AAEhG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,oBAAqB,SAAQ,gBAAgB;IACjD,MAAM,EAAE,eAAe,CAAC;IACxB,SAAS,EAAE,GAAG,CAAC;IACf,WAAW,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,UAAU,EAAE,YAAY,CAAC;IACzB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,SAAS,EAAE,eAAe,GAAG,SAAS,CAAC;IACvC,aAAa,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAClD,kBAAkB,EAAE,QAAQ,GAAG,SAAS,CAAC;IACzC,sBAAsB,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,qBAAqB,EAAE,8BAA8B,CAAC;IACtD,UAAU,EAAE,mBAAmB,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;CACvC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/aztec-node",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.2606882",
|
|
4
4
|
"main": "dest/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
"./sentinel": "./dest/aztec-node/sentinel.js",
|
|
10
10
|
"./test": "./dest/test/index.js"
|
|
11
11
|
},
|
|
12
|
-
"bin": "./dest/bin/index.js",
|
|
13
12
|
"typedocOptions": {
|
|
14
13
|
"entryPoints": [
|
|
15
14
|
"./src/index.ts"
|
|
@@ -20,8 +19,8 @@
|
|
|
20
19
|
"scripts": {
|
|
21
20
|
"start": "node --no-warnings ./dest/bin",
|
|
22
21
|
"start:debug": "node --no-warnings --inspect ./dest/bin",
|
|
23
|
-
"build": "yarn clean && tsc
|
|
24
|
-
"build:dev": "tsc
|
|
22
|
+
"build": "yarn clean && ../scripts/tsc.sh",
|
|
23
|
+
"build:dev": "../scripts/tsc.sh --watch",
|
|
25
24
|
"clean": "rm -rf ./dest .tsbuildinfo",
|
|
26
25
|
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
|
|
27
26
|
},
|
|
@@ -66,38 +65,42 @@
|
|
|
66
65
|
]
|
|
67
66
|
},
|
|
68
67
|
"dependencies": {
|
|
69
|
-
"@aztec/archiver": "0.0.1-commit.
|
|
70
|
-
"@aztec/bb-prover": "0.0.1-commit.
|
|
71
|
-
"@aztec/blob-
|
|
72
|
-
"@aztec/
|
|
73
|
-
"@aztec/
|
|
74
|
-
"@aztec/
|
|
75
|
-
"@aztec/
|
|
76
|
-
"@aztec/
|
|
77
|
-
"@aztec/
|
|
78
|
-
"@aztec/
|
|
79
|
-
"@aztec/node-keystore": "0.0.1-commit.
|
|
80
|
-
"@aztec/node-lib": "0.0.1-commit.
|
|
81
|
-
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.
|
|
82
|
-
"@aztec/p2p": "0.0.1-commit.
|
|
83
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
84
|
-
"@aztec/prover-client": "0.0.1-commit.
|
|
85
|
-
"@aztec/
|
|
86
|
-
"@aztec/
|
|
87
|
-
"@aztec/
|
|
88
|
-
"@aztec/
|
|
89
|
-
"@aztec/
|
|
90
|
-
"@aztec/
|
|
91
|
-
"@aztec/
|
|
68
|
+
"@aztec/archiver": "0.0.1-commit.2606882",
|
|
69
|
+
"@aztec/bb-prover": "0.0.1-commit.2606882",
|
|
70
|
+
"@aztec/blob-client": "0.0.1-commit.2606882",
|
|
71
|
+
"@aztec/blob-lib": "0.0.1-commit.2606882",
|
|
72
|
+
"@aztec/constants": "0.0.1-commit.2606882",
|
|
73
|
+
"@aztec/epoch-cache": "0.0.1-commit.2606882",
|
|
74
|
+
"@aztec/ethereum": "0.0.1-commit.2606882",
|
|
75
|
+
"@aztec/foundation": "0.0.1-commit.2606882",
|
|
76
|
+
"@aztec/kv-store": "0.0.1-commit.2606882",
|
|
77
|
+
"@aztec/l1-artifacts": "0.0.1-commit.2606882",
|
|
78
|
+
"@aztec/node-keystore": "0.0.1-commit.2606882",
|
|
79
|
+
"@aztec/node-lib": "0.0.1-commit.2606882",
|
|
80
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.2606882",
|
|
81
|
+
"@aztec/p2p": "0.0.1-commit.2606882",
|
|
82
|
+
"@aztec/protocol-contracts": "0.0.1-commit.2606882",
|
|
83
|
+
"@aztec/prover-client": "0.0.1-commit.2606882",
|
|
84
|
+
"@aztec/prover-node": "0.0.1-commit.2606882",
|
|
85
|
+
"@aztec/sequencer-client": "0.0.1-commit.2606882",
|
|
86
|
+
"@aztec/simulator": "0.0.1-commit.2606882",
|
|
87
|
+
"@aztec/slasher": "0.0.1-commit.2606882",
|
|
88
|
+
"@aztec/standard-contracts": "0.0.1-commit.2606882",
|
|
89
|
+
"@aztec/stdlib": "0.0.1-commit.2606882",
|
|
90
|
+
"@aztec/telemetry-client": "0.0.1-commit.2606882",
|
|
91
|
+
"@aztec/validator-client": "0.0.1-commit.2606882",
|
|
92
|
+
"@aztec/validator-ha-signer": "0.0.1-commit.2606882",
|
|
93
|
+
"@aztec/world-state": "0.0.1-commit.2606882",
|
|
92
94
|
"koa": "^2.16.1",
|
|
93
95
|
"koa-router": "^13.1.1",
|
|
94
96
|
"tslib": "^2.4.0",
|
|
95
|
-
"viem": "npm:@
|
|
97
|
+
"viem": "npm:@aztec/viem@2.38.2"
|
|
96
98
|
},
|
|
97
99
|
"devDependencies": {
|
|
98
100
|
"@jest/globals": "^30.0.0",
|
|
99
101
|
"@types/jest": "^30.0.0",
|
|
100
102
|
"@types/node": "^22.15.17",
|
|
103
|
+
"@typescript/native-preview": "7.0.0-dev.20260113.1",
|
|
101
104
|
"jest": "^30.0.0",
|
|
102
105
|
"jest-mock-extended": "^4.0.0",
|
|
103
106
|
"ts-node": "^10.9.1",
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { type BlockData, type CommitteeAttestation, L2Block } from '@aztec/stdlib/block';
|
|
3
|
+
import type {
|
|
4
|
+
CheckpointData,
|
|
5
|
+
L1PublishedData,
|
|
6
|
+
ProposedCheckpointData,
|
|
7
|
+
PublishedCheckpoint,
|
|
8
|
+
} from '@aztec/stdlib/checkpoint';
|
|
9
|
+
import {
|
|
10
|
+
type BlockIncludeOptions,
|
|
11
|
+
type BlockResponse,
|
|
12
|
+
type CheckpointIncludeOptions,
|
|
13
|
+
type CheckpointResponse,
|
|
14
|
+
l1PublishInfoFromL1PublishedData,
|
|
15
|
+
} from '@aztec/stdlib/interfaces/client';
|
|
16
|
+
|
|
17
|
+
/** Projects a full {@link L2Block} into a {@link BlockResponse}, attaching L1 / attestation context when provided. */
|
|
18
|
+
export async function blockResponseFromL2Block(
|
|
19
|
+
block: L2Block,
|
|
20
|
+
options: BlockIncludeOptions,
|
|
21
|
+
context?: { l1?: L1PublishedData; attestations?: CommitteeAttestation[] },
|
|
22
|
+
): Promise<BlockResponse> {
|
|
23
|
+
const response: BlockResponse = {
|
|
24
|
+
header: block.header,
|
|
25
|
+
archive: block.archive,
|
|
26
|
+
hash: await block.hash(),
|
|
27
|
+
checkpointNumber: block.checkpointNumber,
|
|
28
|
+
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
29
|
+
number: block.number,
|
|
30
|
+
};
|
|
31
|
+
if (options.includeTransactions) {
|
|
32
|
+
(response as BlockResponse).body = block.body;
|
|
33
|
+
}
|
|
34
|
+
if (options.includeL1PublishInfo) {
|
|
35
|
+
(response as BlockResponse).l1 = l1PublishInfoFromL1PublishedData(context?.l1);
|
|
36
|
+
}
|
|
37
|
+
if (options.includeAttestations) {
|
|
38
|
+
(response as BlockResponse).attestations = context?.attestations ?? [];
|
|
39
|
+
}
|
|
40
|
+
return response;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Projects metadata-only {@link BlockData} into a {@link BlockResponse}. */
|
|
44
|
+
export function blockResponseFromBlockData(
|
|
45
|
+
data: BlockData,
|
|
46
|
+
options: BlockIncludeOptions,
|
|
47
|
+
context?: { l1?: L1PublishedData; attestations?: CommitteeAttestation[] },
|
|
48
|
+
): BlockResponse {
|
|
49
|
+
const response: BlockResponse = {
|
|
50
|
+
header: data.header,
|
|
51
|
+
archive: data.archive,
|
|
52
|
+
hash: data.blockHash,
|
|
53
|
+
checkpointNumber: data.checkpointNumber,
|
|
54
|
+
indexWithinCheckpoint: data.indexWithinCheckpoint,
|
|
55
|
+
number: data.header.getBlockNumber(),
|
|
56
|
+
};
|
|
57
|
+
if (options.includeL1PublishInfo) {
|
|
58
|
+
(response as BlockResponse).l1 = l1PublishInfoFromL1PublishedData(context?.l1);
|
|
59
|
+
}
|
|
60
|
+
if (options.includeAttestations) {
|
|
61
|
+
(response as BlockResponse).attestations = context?.attestations ?? [];
|
|
62
|
+
}
|
|
63
|
+
return response;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Projects a {@link PublishedCheckpoint} into a {@link CheckpointResponse}. */
|
|
67
|
+
export async function checkpointResponseFromPublishedCheckpoint(
|
|
68
|
+
pc: PublishedCheckpoint,
|
|
69
|
+
options: CheckpointIncludeOptions,
|
|
70
|
+
): Promise<CheckpointResponse> {
|
|
71
|
+
const response: CheckpointResponse = {
|
|
72
|
+
number: pc.checkpoint.number,
|
|
73
|
+
header: pc.checkpoint.header,
|
|
74
|
+
archive: pc.checkpoint.archive,
|
|
75
|
+
checkpointOutHash: pc.checkpoint.getCheckpointOutHash(),
|
|
76
|
+
startBlock: pc.checkpoint.blocks[0]?.number ?? BlockNumber.ZERO,
|
|
77
|
+
blockCount: pc.checkpoint.blocks.length,
|
|
78
|
+
feeAssetPriceModifier: pc.checkpoint.feeAssetPriceModifier,
|
|
79
|
+
};
|
|
80
|
+
if (options.includeBlocks) {
|
|
81
|
+
(response as CheckpointResponse).blocks = await Promise.all(
|
|
82
|
+
pc.checkpoint.blocks.map(block =>
|
|
83
|
+
blockResponseFromL2Block(block, {
|
|
84
|
+
includeTransactions: options.includeTransactions,
|
|
85
|
+
includeL1PublishInfo: false,
|
|
86
|
+
includeAttestations: false,
|
|
87
|
+
}),
|
|
88
|
+
),
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
if (options.includeL1PublishInfo) {
|
|
92
|
+
(response as CheckpointResponse).l1 = l1PublishInfoFromL1PublishedData(pc.l1);
|
|
93
|
+
}
|
|
94
|
+
if (options.includeAttestations) {
|
|
95
|
+
(response as CheckpointResponse).attestations = pc.attestations;
|
|
96
|
+
}
|
|
97
|
+
return response;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Projects metadata-only {@link CheckpointData} into a {@link CheckpointResponse}. `includeBlocks` is ignored (no blocks loaded). */
|
|
101
|
+
export function checkpointResponseFromCheckpointData(
|
|
102
|
+
cd: CheckpointData,
|
|
103
|
+
options: CheckpointIncludeOptions,
|
|
104
|
+
): CheckpointResponse {
|
|
105
|
+
const response: CheckpointResponse = {
|
|
106
|
+
number: cd.checkpointNumber,
|
|
107
|
+
header: cd.header,
|
|
108
|
+
archive: cd.archive,
|
|
109
|
+
checkpointOutHash: cd.checkpointOutHash,
|
|
110
|
+
startBlock: cd.startBlock,
|
|
111
|
+
blockCount: cd.blockCount,
|
|
112
|
+
feeAssetPriceModifier: cd.feeAssetPriceModifier,
|
|
113
|
+
};
|
|
114
|
+
if (options.includeL1PublishInfo) {
|
|
115
|
+
(response as CheckpointResponse).l1 = l1PublishInfoFromL1PublishedData(cd.l1);
|
|
116
|
+
}
|
|
117
|
+
if (options.includeAttestations) {
|
|
118
|
+
(response as CheckpointResponse).attestations = cd.attestations;
|
|
119
|
+
}
|
|
120
|
+
return response;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Projects a {@link ProposedCheckpointData} into a {@link CheckpointResponse}.
|
|
125
|
+
* Pure projection — caller pre-fetches `blocks` via `blockSource.getBlocks(...)` when
|
|
126
|
+
* `options.includeBlocks` is true. Throws if `includeL1PublishInfo` or `includeAttestations`
|
|
127
|
+
* is requested (proposed checkpoints have no L1 publish info or attestations).
|
|
128
|
+
*/
|
|
129
|
+
export async function projectProposedToCheckpointResponse(
|
|
130
|
+
proposed: ProposedCheckpointData,
|
|
131
|
+
options: CheckpointIncludeOptions,
|
|
132
|
+
blocks?: L2Block[],
|
|
133
|
+
): Promise<CheckpointResponse> {
|
|
134
|
+
if (options.includeL1PublishInfo || options.includeAttestations) {
|
|
135
|
+
throw new Error('Proposed checkpoints have no L1 publish info or attestations');
|
|
136
|
+
}
|
|
137
|
+
const response: CheckpointResponse = {
|
|
138
|
+
number: proposed.checkpointNumber,
|
|
139
|
+
header: proposed.header,
|
|
140
|
+
archive: proposed.archive,
|
|
141
|
+
checkpointOutHash: proposed.checkpointOutHash,
|
|
142
|
+
startBlock: proposed.startBlock,
|
|
143
|
+
blockCount: proposed.blockCount,
|
|
144
|
+
feeAssetPriceModifier: proposed.feeAssetPriceModifier,
|
|
145
|
+
};
|
|
146
|
+
if (options.includeBlocks) {
|
|
147
|
+
if (!blocks) {
|
|
148
|
+
throw new Error('Blocks must be supplied when includeBlocks is true');
|
|
149
|
+
}
|
|
150
|
+
(response as CheckpointResponse).blocks = await Promise.all(
|
|
151
|
+
blocks.map(block =>
|
|
152
|
+
blockResponseFromL2Block(block, {
|
|
153
|
+
includeTransactions: options.includeTransactions,
|
|
154
|
+
includeL1PublishInfo: false,
|
|
155
|
+
includeAttestations: false,
|
|
156
|
+
}),
|
|
157
|
+
),
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
return response;
|
|
161
|
+
}
|
package/src/aztec-node/config.ts
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import { type ArchiverConfig, archiverConfigMappings } from '@aztec/archiver/config';
|
|
2
|
-
import {
|
|
3
|
-
type GenesisStateConfig,
|
|
4
|
-
type L1ContractAddresses,
|
|
5
|
-
genesisStateConfigMappings,
|
|
6
|
-
l1ContractAddressesMapping,
|
|
7
|
-
} from '@aztec/ethereum';
|
|
2
|
+
import { type GenesisStateConfig, genesisStateConfigMappings } from '@aztec/ethereum/config';
|
|
8
3
|
import { type ConfigMappingsType, booleanConfigHelper, getConfigFromMappings } from '@aztec/foundation/config';
|
|
9
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
10
|
-
import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
|
|
11
5
|
import {
|
|
12
6
|
type KeyStore,
|
|
13
7
|
type ValidatorKeyStore,
|
|
@@ -17,15 +11,21 @@ import {
|
|
|
17
11
|
import { type SharedNodeConfig, sharedNodeConfigMappings } from '@aztec/node-lib/config';
|
|
18
12
|
import { type P2PConfig, p2pConfigMappings } from '@aztec/p2p/config';
|
|
19
13
|
import { type ProverClientUserConfig, proverClientConfigMappings } from '@aztec/prover-client/config';
|
|
14
|
+
import {
|
|
15
|
+
type ProverNodeConfig,
|
|
16
|
+
proverNodeConfigMappings,
|
|
17
|
+
specificProverNodeConfigMappings,
|
|
18
|
+
} from '@aztec/prover-node/config';
|
|
20
19
|
import {
|
|
21
20
|
type SequencerClientConfig,
|
|
22
|
-
type
|
|
21
|
+
type SequencerTxSenderConfig,
|
|
23
22
|
sequencerClientConfigMappings,
|
|
24
23
|
} from '@aztec/sequencer-client/config';
|
|
25
24
|
import { slasherConfigMappings } from '@aztec/slasher';
|
|
26
25
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
27
26
|
import { type NodeRPCConfig, nodeRpcConfigMappings } from '@aztec/stdlib/config';
|
|
28
27
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
28
|
+
import { type DataStoreConfig, dataConfigMappings } from '@aztec/stdlib/kv-store';
|
|
29
29
|
import { type ValidatorClientConfig, validatorClientConfigMappings } from '@aztec/validator-client/config';
|
|
30
30
|
import { type WorldStateConfig, worldStateConfigMappings } from '@aztec/world-state/config';
|
|
31
31
|
|
|
@@ -50,13 +50,22 @@ export type AztecNodeConfig = ArchiverConfig &
|
|
|
50
50
|
SharedNodeConfig &
|
|
51
51
|
GenesisStateConfig &
|
|
52
52
|
NodeRPCConfig &
|
|
53
|
-
SlasherConfig &
|
|
54
|
-
|
|
55
|
-
l1Contracts: L1ContractAddresses;
|
|
53
|
+
SlasherConfig &
|
|
54
|
+
ProverNodeConfig & {
|
|
56
55
|
/** Whether the validator is disabled for this node */
|
|
57
56
|
disableValidator: boolean;
|
|
58
57
|
/** Whether to skip waiting for the archiver to be fully synced before starting other services */
|
|
59
58
|
skipArchiverInitialSync: boolean;
|
|
59
|
+
/** A flag to force verification of tx Chonk proofs. Only used for testnet */
|
|
60
|
+
debugForceTxProofVerification: boolean;
|
|
61
|
+
/** Whether to enable the prover node as a subsystem. */
|
|
62
|
+
enableProverNode: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Test-only: use the deterministic AutomineSequencer instead of the production Sequencer.
|
|
65
|
+
* Requires `aztecTargetCommitteeSize === 0` on the deployed rollup and anvil-backed L1.
|
|
66
|
+
* See `AUTOMINE_E2E_OPTS` in `end-to-end/src/fixtures/fixtures.ts`.
|
|
67
|
+
*/
|
|
68
|
+
useAutomineSequencer?: boolean;
|
|
60
69
|
};
|
|
61
70
|
|
|
62
71
|
export const aztecNodeConfigMappings: ConfigMappingsType<AztecNodeConfig> = {
|
|
@@ -64,6 +73,7 @@ export const aztecNodeConfigMappings: ConfigMappingsType<AztecNodeConfig> = {
|
|
|
64
73
|
...keyStoreConfigMappings,
|
|
65
74
|
...archiverConfigMappings,
|
|
66
75
|
...sequencerClientConfigMappings,
|
|
76
|
+
...proverNodeConfigMappings,
|
|
67
77
|
...validatorClientConfigMappings,
|
|
68
78
|
...proverClientConfigMappings,
|
|
69
79
|
...worldStateConfigMappings,
|
|
@@ -73,10 +83,7 @@ export const aztecNodeConfigMappings: ConfigMappingsType<AztecNodeConfig> = {
|
|
|
73
83
|
...genesisStateConfigMappings,
|
|
74
84
|
...nodeRpcConfigMappings,
|
|
75
85
|
...slasherConfigMappings,
|
|
76
|
-
|
|
77
|
-
description: 'The deployed L1 contract addresses',
|
|
78
|
-
nested: l1ContractAddressesMapping,
|
|
79
|
-
},
|
|
86
|
+
...specificProverNodeConfigMappings,
|
|
80
87
|
disableValidator: {
|
|
81
88
|
env: 'VALIDATOR_DISABLED',
|
|
82
89
|
description: 'Whether the validator is disabled for this node.',
|
|
@@ -87,6 +94,21 @@ export const aztecNodeConfigMappings: ConfigMappingsType<AztecNodeConfig> = {
|
|
|
87
94
|
description: 'Whether to skip waiting for the archiver to be fully synced before starting other services.',
|
|
88
95
|
...booleanConfigHelper(false),
|
|
89
96
|
},
|
|
97
|
+
debugForceTxProofVerification: {
|
|
98
|
+
env: 'DEBUG_FORCE_TX_PROOF_VERIFICATION',
|
|
99
|
+
description: 'Whether to skip waiting for the archiver to be fully synced before starting other services.',
|
|
100
|
+
...booleanConfigHelper(false),
|
|
101
|
+
},
|
|
102
|
+
enableProverNode: {
|
|
103
|
+
env: 'ENABLE_PROVER_NODE',
|
|
104
|
+
description: 'Whether to enable the prover node as a subsystem.',
|
|
105
|
+
...booleanConfigHelper(false),
|
|
106
|
+
},
|
|
107
|
+
useAutomineSequencer: {
|
|
108
|
+
env: 'USE_AUTOMINE_SEQUENCER',
|
|
109
|
+
description: 'Test-only: use AutomineSequencer instead of the production Sequencer.',
|
|
110
|
+
...booleanConfigHelper(false),
|
|
111
|
+
},
|
|
90
112
|
};
|
|
91
113
|
|
|
92
114
|
/**
|
|
@@ -97,7 +119,7 @@ export function getConfigEnvVars(): AztecNodeConfig {
|
|
|
97
119
|
return getConfigFromMappings<AztecNodeConfig>(aztecNodeConfigMappings);
|
|
98
120
|
}
|
|
99
121
|
|
|
100
|
-
type ConfigRequiredToBuildKeyStore =
|
|
122
|
+
type ConfigRequiredToBuildKeyStore = SequencerClientConfig & SharedNodeConfig & ValidatorClientConfig;
|
|
101
123
|
|
|
102
124
|
function createKeyStoreFromWeb3Signer(config: ConfigRequiredToBuildKeyStore): KeyStore | undefined {
|
|
103
125
|
const validatorKeyStores: ValidatorKeyStore[] = [];
|
|
@@ -116,7 +138,7 @@ function createKeyStoreFromWeb3Signer(config: ConfigRequiredToBuildKeyStore): Ke
|
|
|
116
138
|
feeRecipient: config.feeRecipient ?? AztecAddress.ZERO,
|
|
117
139
|
coinbase: config.coinbase ?? config.validatorAddresses[0],
|
|
118
140
|
remoteSigner: config.web3SignerUrl,
|
|
119
|
-
publisher: config.
|
|
141
|
+
publisher: config.sequencerPublisherAddresses ?? [],
|
|
120
142
|
});
|
|
121
143
|
|
|
122
144
|
const keyStore: KeyStore = {
|
|
@@ -132,7 +154,7 @@ function createKeyStoreFromWeb3Signer(config: ConfigRequiredToBuildKeyStore): Ke
|
|
|
132
154
|
function createKeyStoreFromPrivateKeys(config: ConfigRequiredToBuildKeyStore): KeyStore | undefined {
|
|
133
155
|
const validatorKeyStores: ValidatorKeyStore[] = [];
|
|
134
156
|
const ethPrivateKeys = config.validatorPrivateKeys
|
|
135
|
-
? config.validatorPrivateKeys.getValue().map(x => ethPrivateKeySchema.parse(x))
|
|
157
|
+
? config.validatorPrivateKeys.getValue().map((x: string) => ethPrivateKeySchema.parse(x))
|
|
136
158
|
: [];
|
|
137
159
|
|
|
138
160
|
if (!ethPrivateKeys.length) {
|
|
@@ -141,8 +163,10 @@ function createKeyStoreFromPrivateKeys(config: ConfigRequiredToBuildKeyStore): K
|
|
|
141
163
|
const coinbase = config.coinbase ?? EthAddress.fromString(privateKeyToAddress(ethPrivateKeys[0]));
|
|
142
164
|
const feeRecipient = config.feeRecipient ?? AztecAddress.ZERO;
|
|
143
165
|
|
|
144
|
-
const publisherKeys = config.
|
|
145
|
-
? config.
|
|
166
|
+
const publisherKeys = config.sequencerPublisherPrivateKeys
|
|
167
|
+
? config.sequencerPublisherPrivateKeys.map((k: { getValue: () => string }) =>
|
|
168
|
+
ethPrivateKeySchema.parse(k.getValue()),
|
|
169
|
+
)
|
|
146
170
|
: [];
|
|
147
171
|
|
|
148
172
|
validatorKeyStores.push({
|
|
@@ -164,7 +188,7 @@ function createKeyStoreFromPrivateKeys(config: ConfigRequiredToBuildKeyStore): K
|
|
|
164
188
|
}
|
|
165
189
|
|
|
166
190
|
export function createKeyStoreForValidator(
|
|
167
|
-
config:
|
|
191
|
+
config: SequencerTxSenderConfig & SequencerClientConfig & SharedNodeConfig,
|
|
168
192
|
): KeyStore | undefined {
|
|
169
193
|
if (config.web3SignerUrl !== undefined && config.web3SignerUrl.length > 0) {
|
|
170
194
|
return createKeyStoreFromWeb3Signer(config);
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
Metrics,
|
|
5
5
|
type TelemetryClient,
|
|
6
6
|
type UpDownCounter,
|
|
7
|
-
|
|
7
|
+
createUpDownCounterWithDefault,
|
|
8
8
|
} from '@aztec/telemetry-client';
|
|
9
9
|
|
|
10
10
|
export class NodeMetrics {
|
|
@@ -16,25 +16,14 @@ export class NodeMetrics {
|
|
|
16
16
|
|
|
17
17
|
constructor(client: TelemetryClient, name = 'AztecNode') {
|
|
18
18
|
const meter = client.getMeter(name);
|
|
19
|
-
this.receiveTxCount = meter
|
|
20
|
-
|
|
21
|
-
description: 'The duration of the receiveTx method',
|
|
22
|
-
unit: 'ms',
|
|
23
|
-
valueType: ValueType.INT,
|
|
19
|
+
this.receiveTxCount = createUpDownCounterWithDefault(meter, Metrics.NODE_RECEIVE_TX_COUNT, {
|
|
20
|
+
[Attributes.OK]: [true, false],
|
|
24
21
|
});
|
|
22
|
+
this.receiveTxDuration = meter.createHistogram(Metrics.NODE_RECEIVE_TX_DURATION);
|
|
25
23
|
|
|
26
|
-
this.snapshotDuration = meter.createHistogram(Metrics.NODE_SNAPSHOT_DURATION
|
|
27
|
-
description: 'How long taking a snapshot takes',
|
|
28
|
-
unit: 'ms',
|
|
29
|
-
valueType: ValueType.INT,
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
this.snapshotErrorCount = meter.createUpDownCounter(Metrics.NODE_SNAPSHOT_ERROR_COUNT, {
|
|
33
|
-
description: 'How many snapshot errors have happened',
|
|
34
|
-
valueType: ValueType.INT,
|
|
35
|
-
});
|
|
24
|
+
this.snapshotDuration = meter.createHistogram(Metrics.NODE_SNAPSHOT_DURATION);
|
|
36
25
|
|
|
37
|
-
this.snapshotErrorCount.
|
|
26
|
+
this.snapshotErrorCount = createUpDownCounterWithDefault(meter, Metrics.NODE_SNAPSHOT_ERROR_COUNT);
|
|
38
27
|
}
|
|
39
28
|
|
|
40
29
|
receivedTx(durationMs: number, isAccepted: boolean) {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { PublicDataWrite } from '@aztec/stdlib/avm';
|
|
2
|
+
import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
|
|
3
|
+
import type { PublicStorageOverride } from '@aztec/stdlib/interfaces/client';
|
|
4
|
+
import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
|
|
5
|
+
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Injects public-state overrides into an (ephemeral) world-state fork before simulation.
|
|
9
|
+
*
|
|
10
|
+
* Each override is written via the same `sequentialInsert` path the public processor
|
|
11
|
+
* uses during real transaction execution, so low-leaf updates and root coherence are
|
|
12
|
+
* handled identically for both simulation and proof generation.
|
|
13
|
+
*
|
|
14
|
+
* Writes never reach committed world state — the fork is thrown away after simulation.
|
|
15
|
+
*/
|
|
16
|
+
export async function applyPublicDataOverrides(
|
|
17
|
+
fork: MerkleTreeWriteOperations,
|
|
18
|
+
publicStorage: PublicStorageOverride[] | undefined,
|
|
19
|
+
): Promise<void> {
|
|
20
|
+
if (!publicStorage?.length) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const writes = await Promise.all(
|
|
25
|
+
publicStorage.map(async o => {
|
|
26
|
+
const leafSlot = await computePublicDataTreeLeafSlot(o.contract, o.slot);
|
|
27
|
+
return new PublicDataWrite(leafSlot, o.value);
|
|
28
|
+
}),
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
await fork.sequentialInsert(
|
|
32
|
+
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
33
|
+
writes.map(w => w.toBuffer()),
|
|
34
|
+
);
|
|
35
|
+
}
|