@aztec/aztec-node 6.0.0-nightly.20260810 → 6.0.0-nightly.20260821
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/node_public_calls_simulator.d.ts +15 -4
- package/dest/aztec-node/node_public_calls_simulator.d.ts.map +1 -1
- package/dest/aztec-node/node_public_calls_simulator.js +76 -47
- package/dest/aztec-node/register_node_rpc_handlers.d.ts +2 -1
- package/dest/aztec-node/register_node_rpc_handlers.d.ts.map +1 -1
- package/dest/aztec-node/register_node_rpc_handlers.js +19 -2
- package/dest/aztec-node/server.d.ts +2 -2
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +14 -7
- package/dest/bin/index.js +20 -9
- package/dest/factory.d.ts +1 -1
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +11 -5
- package/dest/modules/node_world_state_queries.d.ts +4 -4
- package/dest/modules/node_world_state_queries.d.ts.map +1 -1
- package/dest/modules/node_world_state_queries.js +2 -4
- package/package.json +28 -28
- package/src/aztec-node/node_public_calls_simulator.ts +97 -58
- package/src/aztec-node/register_node_rpc_handlers.ts +16 -4
- package/src/aztec-node/server.ts +12 -7
- package/src/bin/index.ts +24 -8
- package/src/factory.ts +16 -10
- package/src/modules/node_world_state_queries.ts +4 -5
package/dest/factory.d.ts
CHANGED
|
@@ -30,4 +30,4 @@ export interface CreateAztecNodeOptions {
|
|
|
30
30
|
* @returns A fully synced Aztec Node for use in development/testing.
|
|
31
31
|
*/
|
|
32
32
|
export declare function createAztecNodeService(inputConfig: AztecNodeConfig, deps?: CreateAztecNodeDeps, options?: CreateAztecNodeOptions): Promise<AztecNodeService>;
|
|
33
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBWUEsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUl2RCxPQUFPLEVBQUUsS0FBSyxhQUFhLEVBQW1CLE1BQU0sWUFBWSxDQUFDO0FBQ2pFLE9BQU8sRUFBbUIsS0FBSyxjQUFjLEVBQW9CLE1BQU0sb0JBQW9CLENBQUM7QUFFNUYsT0FBTyxFQUlMLEtBQUssa0JBQWtCLEVBQ3hCLE1BQU0seUJBQXlCLENBQUM7QUFpQmpDLE9BQU8sS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzdELE9BQU8sRUFBRSxLQUFLLGVBQWUsRUFBc0IsTUFBTSx5QkFBeUIsQ0FBQztBQVVuRixPQUFPLEtBQUssRUFBRSwwQkFBMEIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBS25GLE9BQU8sRUFBRSxLQUFLLGVBQWUsRUFBOEIsTUFBTSx3QkFBd0IsQ0FBQztBQUMxRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUcxRCxvR0FBb0c7QUFDcEcsTUFBTSxXQUFXLG1CQUFtQjtJQUNsQyxTQUFTLENBQUMsRUFBRSxlQUFlLENBQUM7SUFDNUIsTUFBTSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ2hCLFNBQVMsQ0FBQyxFQUFFLGtCQUFrQixDQUFDO0lBQy9CLFlBQVksQ0FBQyxFQUFFLFlBQVksQ0FBQztJQUM1QixhQUFhLENBQUMsRUFBRSxhQUFhLENBQUM7SUFDOUIsY0FBYyxDQUFDLEVBQUUsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3pDLG9CQUFvQixDQUFDLEVBQUUsMEJBQTBCLENBQUM7Q0FDbkQ7QUFFRCw2RUFBNkU7QUFDN0UsTUFBTSxXQUFXLHNCQUFzQjtJQUNyQyxPQUFPLENBQUMsRUFBRSxXQUFXLENBQUM7SUFDdEIsa0JBQWtCLENBQUMsRUFBRSxPQUFPLENBQUM7SUFDN0IsbUJBQW1CLENBQUMsRUFBRSxPQUFPLENBQUM7Q0FDL0I7QUFFRDs7OztHQUlHO0FBQ0gsd0JBQXNCLHNCQUFzQixDQUMxQyxXQUFXLEVBQUUsZUFBZSxFQUM1QixJQUFJLEdBQUUsbUJBQXdCLEVBQzlCLE9BQU8sR0FBRSxzQkFBMkIsR0FDbkMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENBMmtCM0IifQ==
|
package/dest/factory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAIvD,OAAO,EAAE,KAAK,aAAa,EAAmB,MAAM,YAAY,CAAC;AACjE,OAAO,EAAmB,KAAK,cAAc,EAAoB,MAAM,oBAAoB,CAAC;AAE5F,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,yBAAyB,CAAC;AAiBjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAUnF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAKnF,OAAO,EAAE,KAAK,eAAe,EAA8B,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,oGAAoG;AACpG,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACzC,oBAAoB,CAAC,EAAE,0BAA0B,CAAC;CACnD;AAED,6EAA6E;AAC7E,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,eAAe,EAC5B,IAAI,GAAE,mBAAwB,EAC9B,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAIvD,OAAO,EAAE,KAAK,aAAa,EAAmB,MAAM,YAAY,CAAC;AACjE,OAAO,EAAmB,KAAK,cAAc,EAAoB,MAAM,oBAAoB,CAAC;AAE5F,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,yBAAyB,CAAC;AAiBjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAUnF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAKnF,OAAO,EAAE,KAAK,eAAe,EAA8B,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,oGAAoG;AACpG,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACzC,oBAAoB,CAAC,EAAE,0BAA0B,CAAC;CACnD;AAED,6EAA6E;AAC7E,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,eAAe,EAC5B,IAAI,GAAE,mBAAwB,EAC9B,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,gBAAgB,CAAC,CA2kB3B"}
|
package/dest/factory.js
CHANGED
|
@@ -285,11 +285,17 @@ import { createSentinel } from './sentinel/factory.js';
|
|
|
285
285
|
watchers.push(validatorsSentinel);
|
|
286
286
|
}
|
|
287
287
|
if (collectOffenses) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
288
|
+
// The watcher's only evidence is the absence of gossiped txs in the local pool, so it cannot make a
|
|
289
|
+
// valid claim on a node that runs no p2p stack at all. Skipped entirely rather than gated at runtime.
|
|
290
|
+
if (config.p2pEnabled) {
|
|
291
|
+
dataWithholdingWatcher = new DataWithholdingWatcher(epochCache, archiver, p2pClient.getTxProvider(), p2pClient, reexecutionTracker, {
|
|
292
|
+
chainId: config.l1ChainId,
|
|
293
|
+
rollupAddress: config.rollupAddress
|
|
294
|
+
}, config);
|
|
295
|
+
watchers.push(dataWithholdingWatcher);
|
|
296
|
+
} else {
|
|
297
|
+
log.verbose('Skipping data-withholding watcher since p2p is disabled');
|
|
298
|
+
}
|
|
293
299
|
broadcastedInvalidCheckpointProposalWatcher = new BroadcastedInvalidCheckpointProposalWatcher(p2pClient, archiver, epochCache, config);
|
|
294
300
|
watchers.push(broadcastedInvalidCheckpointProposalWatcher);
|
|
295
301
|
// The proposal handler (validator-owned or standalone) is the source of invalid-proposal/equivocation
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { ARCHIVE_HEIGHT, type L1_TO_L2_MSG_TREE_HEIGHT, type NOTE_HASH_TREE_HEIGHT } from '@aztec/constants';
|
|
2
|
-
import { type
|
|
2
|
+
import { type EpochNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
4
|
import { type Logger } from '@aztec/foundation/log';
|
|
5
5
|
import { MembershipWitness, type SiblingPath } from '@aztec/foundation/trees';
|
|
6
6
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
7
7
|
import { type BlockHash, type BlockParameter, type DataInBlock, type L2BlockSource } from '@aztec/stdlib/block';
|
|
8
8
|
import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
9
|
-
import {
|
|
9
|
+
import type { L1ToL2MessageSource, L2ToL1MembershipWitness } from '@aztec/stdlib/messaging';
|
|
10
10
|
import { MerkleTreeId, NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
11
11
|
import type { TxHash } from '@aztec/stdlib/tx';
|
|
12
12
|
/** Dependencies required to build a {@link NodeWorldStateQueries}. */
|
|
@@ -32,7 +32,7 @@ export declare class NodeWorldStateQueries {
|
|
|
32
32
|
getBlockHashMembershipWitness(referenceBlock: BlockParameter, blockHash: BlockHash): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined>;
|
|
33
33
|
getNoteHashMembershipWitness(referenceBlock: BlockParameter, noteHash: Fr): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined>;
|
|
34
34
|
getL1ToL2MessageMembershipWitness(referenceBlock: BlockParameter, l1ToL2Message: Fr): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>] | undefined>;
|
|
35
|
-
|
|
35
|
+
getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise<bigint | undefined>;
|
|
36
36
|
/**
|
|
37
37
|
* Returns all the L2 to L1 messages in an epoch (empty array if the epoch is not found). The public
|
|
38
38
|
* `AztecNodeService.getL2ToL1Messages` that delegates here is deprecated in favor of
|
|
@@ -62,4 +62,4 @@ export declare class NodeWorldStateQueries {
|
|
|
62
62
|
*/
|
|
63
63
|
getWorldState(block: BlockParameter): Promise<import("@aztec/world-state").MerkleTreeReadOperations>;
|
|
64
64
|
}
|
|
65
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
65
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV93b3JsZF9zdGF0ZV9xdWVyaWVzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbW9kdWxlcy9ub2RlX3dvcmxkX3N0YXRlX3F1ZXJpZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGNBQWMsRUFBRSxLQUFLLHdCQUF3QixFQUFFLEtBQUsscUJBQXFCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM3RyxPQUFPLEVBQWUsS0FBSyxXQUFXLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVoRixPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDcEQsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBRWxFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxLQUFLLFdBQVcsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzlFLE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2hFLE9BQU8sRUFDTCxLQUFLLFNBQVMsRUFDZCxLQUFLLGNBQWMsRUFDbkIsS0FBSyxXQUFXLEVBQ2hCLEtBQUssYUFBYSxFQUduQixNQUFNLHFCQUFxQixDQUFDO0FBRTdCLE9BQU8sS0FBSyxFQUFFLHNCQUFzQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDOUUsT0FBTyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RixPQUFPLEVBQ0wsWUFBWSxFQUVaLDBCQUEwQixFQUUxQixpQkFBaUIsRUFDbEIsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQVcvQyxzRUFBc0U7QUFDdEUsTUFBTSxXQUFXLHlCQUF5QjtJQUN4QyxzQkFBc0IsRUFBRSxzQkFBc0IsQ0FBQztJQUMvQyxXQUFXLEVBQUUsYUFBYSxDQUFDO0lBQzNCLG1C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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node_world_state_queries.d.ts","sourceRoot":"","sources":["../../src/modules/node_world_state_queries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,wBAAwB,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC7G,OAAO,EAAe,KAAK,
|
|
1
|
+
{"version":3,"file":"node_world_state_queries.d.ts","sourceRoot":"","sources":["../../src/modules/node_world_state_queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,6 @@ import { sleep } from '@aztec/foundation/sleep';
|
|
|
6
6
|
import { MembershipWitness } from '@aztec/foundation/trees';
|
|
7
7
|
import { inspectBlockParameter } from '@aztec/stdlib/block';
|
|
8
8
|
import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
|
|
9
|
-
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
10
9
|
import { MerkleTreeId, NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
11
10
|
import { WorldStateSynchronizerError } from '@aztec/world-state';
|
|
12
11
|
import { normalizeBlockParameter } from './block_parameter.js';
|
|
@@ -116,9 +115,8 @@ import { normalizeBlockParameter } from './block_parameter.js';
|
|
|
116
115
|
witness.path
|
|
117
116
|
];
|
|
118
117
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return messageIndex !== undefined ? InboxLeaf.checkpointNumberFromIndex(messageIndex) : undefined;
|
|
118
|
+
getL1ToL2MessageIndex(l1ToL2Message) {
|
|
119
|
+
return this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message);
|
|
122
120
|
}
|
|
123
121
|
/**
|
|
124
122
|
* Returns all the L2 to L1 messages in an epoch (empty array if the epoch is not found). The public
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/aztec-node",
|
|
3
|
-
"version": "6.0.0-nightly.
|
|
3
|
+
"version": "6.0.0-nightly.20260821",
|
|
4
4
|
"main": "dest/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -65,39 +65,39 @@
|
|
|
65
65
|
]
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@aztec/archiver": "6.0.0-nightly.
|
|
69
|
-
"@aztec/bb-prover": "6.0.0-nightly.
|
|
70
|
-
"@aztec/bb.js": "6.0.0-nightly.
|
|
71
|
-
"@aztec/blob-client": "6.0.0-nightly.
|
|
72
|
-
"@aztec/blob-lib": "6.0.0-nightly.
|
|
73
|
-
"@aztec/constants": "6.0.0-nightly.
|
|
74
|
-
"@aztec/epoch-cache": "6.0.0-nightly.
|
|
75
|
-
"@aztec/ethereum": "6.0.0-nightly.
|
|
76
|
-
"@aztec/foundation": "6.0.0-nightly.
|
|
77
|
-
"@aztec/kv-store": "6.0.0-nightly.
|
|
78
|
-
"@aztec/l1-artifacts": "6.0.0-nightly.
|
|
79
|
-
"@aztec/node-keystore": "6.0.0-nightly.
|
|
80
|
-
"@aztec/node-lib": "6.0.0-nightly.
|
|
81
|
-
"@aztec/p2p": "6.0.0-nightly.
|
|
82
|
-
"@aztec/protocol-contracts": "6.0.0-nightly.
|
|
83
|
-
"@aztec/prover-client": "6.0.0-nightly.
|
|
84
|
-
"@aztec/prover-node": "6.0.0-nightly.
|
|
85
|
-
"@aztec/sequencer-client": "6.0.0-nightly.
|
|
86
|
-
"@aztec/simulator": "6.0.0-nightly.
|
|
87
|
-
"@aztec/slasher": "6.0.0-nightly.
|
|
88
|
-
"@aztec/standard-contracts": "6.0.0-nightly.
|
|
89
|
-
"@aztec/stdlib": "6.0.0-nightly.
|
|
90
|
-
"@aztec/telemetry-client": "6.0.0-nightly.
|
|
91
|
-
"@aztec/validator-client": "6.0.0-nightly.
|
|
92
|
-
"@aztec/validator-ha-signer": "6.0.0-nightly.
|
|
93
|
-
"@aztec/world-state": "6.0.0-nightly.
|
|
68
|
+
"@aztec/archiver": "6.0.0-nightly.20260821",
|
|
69
|
+
"@aztec/bb-prover": "6.0.0-nightly.20260821",
|
|
70
|
+
"@aztec/bb.js": "6.0.0-nightly.20260819",
|
|
71
|
+
"@aztec/blob-client": "6.0.0-nightly.20260821",
|
|
72
|
+
"@aztec/blob-lib": "6.0.0-nightly.20260821",
|
|
73
|
+
"@aztec/constants": "6.0.0-nightly.20260821",
|
|
74
|
+
"@aztec/epoch-cache": "6.0.0-nightly.20260821",
|
|
75
|
+
"@aztec/ethereum": "6.0.0-nightly.20260821",
|
|
76
|
+
"@aztec/foundation": "6.0.0-nightly.20260821",
|
|
77
|
+
"@aztec/kv-store": "6.0.0-nightly.20260821",
|
|
78
|
+
"@aztec/l1-artifacts": "6.0.0-nightly.20260819",
|
|
79
|
+
"@aztec/node-keystore": "6.0.0-nightly.20260821",
|
|
80
|
+
"@aztec/node-lib": "6.0.0-nightly.20260821",
|
|
81
|
+
"@aztec/p2p": "6.0.0-nightly.20260821",
|
|
82
|
+
"@aztec/protocol-contracts": "6.0.0-nightly.20260821",
|
|
83
|
+
"@aztec/prover-client": "6.0.0-nightly.20260821",
|
|
84
|
+
"@aztec/prover-node": "6.0.0-nightly.20260821",
|
|
85
|
+
"@aztec/sequencer-client": "6.0.0-nightly.20260821",
|
|
86
|
+
"@aztec/simulator": "6.0.0-nightly.20260821",
|
|
87
|
+
"@aztec/slasher": "6.0.0-nightly.20260821",
|
|
88
|
+
"@aztec/standard-contracts": "6.0.0-nightly.20260821",
|
|
89
|
+
"@aztec/stdlib": "6.0.0-nightly.20260821",
|
|
90
|
+
"@aztec/telemetry-client": "6.0.0-nightly.20260821",
|
|
91
|
+
"@aztec/validator-client": "6.0.0-nightly.20260821",
|
|
92
|
+
"@aztec/validator-ha-signer": "6.0.0-nightly.20260821",
|
|
93
|
+
"@aztec/world-state": "6.0.0-nightly.20260821",
|
|
94
94
|
"koa": "^2.16.1",
|
|
95
95
|
"koa-router": "^13.1.1",
|
|
96
96
|
"tslib": "^2.4.0",
|
|
97
97
|
"viem": "npm:@aztec/viem@2.38.2"
|
|
98
98
|
},
|
|
99
99
|
"devDependencies": {
|
|
100
|
-
"@aztec/noir-protocol-circuits-types": "6.0.0-nightly.
|
|
100
|
+
"@aztec/noir-protocol-circuits-types": "6.0.0-nightly.20260821",
|
|
101
101
|
"@jest/globals": "^30.0.0",
|
|
102
102
|
"@types/jest": "^30.0.0",
|
|
103
103
|
"@types/node": "^22.15.17",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MAX_L1_TO_L2_MSGS_PER_BLOCK, MAX_L1_TO_L2_MSGS_PER_CHECKPOINT } from '@aztec/constants';
|
|
2
2
|
import { PROPOSER_PIPELINING_SLOT_OFFSET } from '@aztec/epoch-cache';
|
|
3
3
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
4
4
|
import {
|
|
@@ -8,21 +8,21 @@ import {
|
|
|
8
8
|
} from '@aztec/ethereum/contracts';
|
|
9
9
|
import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
10
10
|
import { compactArray } from '@aztec/foundation/collection';
|
|
11
|
-
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
12
11
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
13
12
|
import { BadRequestError } from '@aztec/foundation/json-rpc';
|
|
14
13
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
15
14
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
16
|
-
import {
|
|
15
|
+
import { type InboxBucketSource, selectInboxBucketForBlock } from '@aztec/sequencer-client';
|
|
17
16
|
import { type AvmSimulator, PublicContractsDB, PublicProcessorFactory } from '@aztec/simulator/server';
|
|
18
17
|
import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
19
18
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
20
19
|
import type { L2BlockSource, L2Tips } from '@aztec/stdlib/block';
|
|
21
20
|
import { type ProposedCheckpointData, buildCheckpointSimulationOverridesPlan } from '@aztec/stdlib/checkpoint';
|
|
22
21
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
23
|
-
import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
24
|
-
import { type L1ToL2MessageSource, appendL1ToL2MessagesToTree } from '@aztec/stdlib/messaging';
|
|
22
|
+
import type { MerkleTreeWriteOperations, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
23
|
+
import { type L1ToL2MessageSource, appendL1ToL2MessagesToTree, getInboxCutoffTimestamp } from '@aztec/stdlib/messaging';
|
|
25
24
|
import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p';
|
|
25
|
+
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
26
26
|
import {
|
|
27
27
|
type GlobalVariableBuilder,
|
|
28
28
|
GlobalVariables,
|
|
@@ -34,6 +34,9 @@ import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-clien
|
|
|
34
34
|
|
|
35
35
|
import { applyPublicDataOverrides } from './public_data_overrides.js';
|
|
36
36
|
|
|
37
|
+
/** Inbox queries the simulator needs to predict the message bundle the next block would consume. */
|
|
38
|
+
type SimulatorInboxSource = InboxBucketSource & Pick<L1ToL2MessageSource, 'getInboxBucketByTotalMsgCount'>;
|
|
39
|
+
|
|
37
40
|
/** Config fields the simulator needs — a narrow subset of `AztecNodeConfig`. */
|
|
38
41
|
export interface NodePublicCallsSimulatorConfig {
|
|
39
42
|
/** Maximum total gas limit accepted for an incoming simulation. */
|
|
@@ -46,7 +49,8 @@ export interface NodePublicCallsSimulatorConfig {
|
|
|
46
49
|
export interface NodePublicCallsSimulatorDeps {
|
|
47
50
|
blockSource: L2BlockSource;
|
|
48
51
|
worldStateSynchronizer: WorldStateSynchronizer;
|
|
49
|
-
|
|
52
|
+
/** Inbox bucket queries, used to predict the L1-to-L2 messages the next block will consume. */
|
|
53
|
+
l1ToL2MessageSource: SimulatorInboxSource;
|
|
50
54
|
contractDataSource: ContractDataSource;
|
|
51
55
|
globalVariableBuilder: GlobalVariableBuilder;
|
|
52
56
|
/**
|
|
@@ -78,16 +82,20 @@ export interface NodePublicCallsSimulatorDeps {
|
|
|
78
82
|
* - **When the next block continues an in-progress checkpoint** (the latest proposed block is ahead of
|
|
79
83
|
* the proposed-checkpoint frontier): every block in a checkpoint shares the same
|
|
80
84
|
* `CheckpointGlobalVariables`, so we copy the latest proposed block's globals verbatim and only
|
|
81
|
-
* bump the block number. No L1 calls
|
|
85
|
+
* bump the block number. No L1 calls.
|
|
82
86
|
* - **When the next block opens a new checkpoint** (the latest proposed block coincides with the
|
|
83
87
|
* proposed-checkpoint frontier): we compute fresh globals for the slot the next block will land in,
|
|
84
88
|
* applying the same `SimulationOverridesPlan` the sequencer applies so the simulated mana min fee
|
|
85
89
|
* matches what the sequencer will write into the block header.
|
|
90
|
+
*
|
|
91
|
+
* Either way it also predicts the L1-to-L2 message bundle the next block would consume and appends it
|
|
92
|
+
* to the fork, so a transaction consuming a message that is in the Inbox but not yet in a block
|
|
93
|
+
* simulates against the state it will actually run in.
|
|
86
94
|
*/
|
|
87
95
|
export class NodePublicCallsSimulator {
|
|
88
96
|
private readonly blockSource: L2BlockSource;
|
|
89
97
|
private readonly worldStateSynchronizer: WorldStateSynchronizer;
|
|
90
|
-
private readonly l1ToL2MessageSource:
|
|
98
|
+
private readonly l1ToL2MessageSource: SimulatorInboxSource;
|
|
91
99
|
private readonly contractDataSource: ContractDataSource;
|
|
92
100
|
private readonly globalVariableBuilder: GlobalVariableBuilder;
|
|
93
101
|
private readonly rollupContract: RollupContract | undefined;
|
|
@@ -97,6 +105,7 @@ export class NodePublicCallsSimulator {
|
|
|
97
105
|
private readonly avmSimulator?: AvmSimulator;
|
|
98
106
|
private readonly telemetry: TelemetryClient;
|
|
99
107
|
private readonly log: Logger;
|
|
108
|
+
private readonly dateProvider = new DateProvider();
|
|
100
109
|
|
|
101
110
|
constructor(deps: NodePublicCallsSimulatorDeps) {
|
|
102
111
|
this.blockSource = deps.blockSource;
|
|
@@ -157,9 +166,7 @@ export class NodePublicCallsSimulator {
|
|
|
157
166
|
// the proposed-checkpoint terminating block; it opens a new checkpoint when they coincide.
|
|
158
167
|
const atCheckpointBoundary = proposedCheckpointLastBlock === l2Tips.proposed.number;
|
|
159
168
|
|
|
160
|
-
|
|
161
|
-
// before simulation. Only set when opening a new checkpoint, where the next block is its first block.
|
|
162
|
-
const { globalVariables: newGlobalVariables, targetCheckpoint } = atCheckpointBoundary
|
|
169
|
+
const { globalVariables: newGlobalVariables } = atCheckpointBoundary
|
|
163
170
|
? await this.buildGlobalVariablesForNewCheckpoint(l2Tips, proposedCheckpointData, blockNumber)
|
|
164
171
|
: { globalVariables: await this.copyGlobalVariablesFromLatestProposedBlock(latestBlockNumber, blockNumber) };
|
|
165
172
|
|
|
@@ -169,7 +176,7 @@ export class NodePublicCallsSimulator {
|
|
|
169
176
|
const publicProcessorFactory = new PublicProcessorFactory(
|
|
170
177
|
this.contractDataSource,
|
|
171
178
|
this.avmSimulator,
|
|
172
|
-
|
|
179
|
+
this.dateProvider,
|
|
173
180
|
this.telemetry,
|
|
174
181
|
this.log.getBindings(),
|
|
175
182
|
);
|
|
@@ -184,18 +191,14 @@ export class NodePublicCallsSimulator {
|
|
|
184
191
|
// Ensure world-state has caught up with the latest block we loaded from the archiver
|
|
185
192
|
await this.worldStateSynchronizer.syncImmediate(latestBlockNumber);
|
|
186
193
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
// Request a new fork of the world state at the latest block number, and apply any overrides and next checkpoint messages to it before simulation
|
|
194
|
+
// Request a new fork of the world state at the latest block number, then apply the next block's predicted
|
|
195
|
+
// L1-to-L2 message bundle and any caller overrides to it before simulation.
|
|
190
196
|
await using merkleTreeFork = await this.worldStateSynchronizer.fork(latestBlockNumber);
|
|
191
197
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
);
|
|
197
|
-
await appendL1ToL2MessagesToTree(merkleTreeFork, nextCheckpointMessages);
|
|
198
|
-
}
|
|
198
|
+
await this.appendPredictedL1ToL2Messages(merkleTreeFork, {
|
|
199
|
+
slotNumber: newGlobalVariables.slotNumber,
|
|
200
|
+
checkpointStartBlock: atCheckpointBoundary ? undefined : proposedCheckpointLastBlock,
|
|
201
|
+
});
|
|
199
202
|
|
|
200
203
|
await applyPublicDataOverrides(merkleTreeFork, overrides?.publicStorage);
|
|
201
204
|
|
|
@@ -236,47 +239,89 @@ export class NodePublicCallsSimulator {
|
|
|
236
239
|
}
|
|
237
240
|
|
|
238
241
|
/**
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
242
|
+
* Appends the L1-to-L2 message bundle the next block would consume to the simulation fork, so a transaction
|
|
243
|
+
* consuming a message that has reached the Inbox but no block yet simulates against the state it will run in.
|
|
244
|
+
* Runs the same bucket selection the sequencer runs (lag eligibility plus the per-block and per-checkpoint caps),
|
|
245
|
+
* treating the next block as non-final: the censorship cutoff only widens consumption on a checkpoint's last
|
|
246
|
+
* block, and the node cannot know whether the next block is it.
|
|
247
|
+
*
|
|
248
|
+
* Best-effort. Any failure — Inbox buckets not synced yet, a torn archiver snapshot — leaves the fork at the tip
|
|
249
|
+
* state, which is what the transaction sees if the next block consumes nothing.
|
|
245
250
|
*/
|
|
246
|
-
private async
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
251
|
+
private async appendPredictedL1ToL2Messages(
|
|
252
|
+
fork: MerkleTreeWriteOperations,
|
|
253
|
+
opts: {
|
|
254
|
+
/** Slot the next block lands in; anchors the censorship cutoff. */
|
|
255
|
+
slotNumber: SlotNumber;
|
|
256
|
+
/** Last block of the checkpoint the next block extends; undefined when the next block opens a checkpoint. */
|
|
257
|
+
checkpointStartBlock: BlockNumber | undefined;
|
|
258
|
+
},
|
|
259
|
+
): Promise<void> {
|
|
250
260
|
try {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
if (
|
|
254
|
-
this.log.
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
} else {
|
|
259
|
-
this.log.error(
|
|
260
|
-
`Failed to get L1-to-L2 messages for checkpoint ${targetCheckpoint} (simulating without them)`,
|
|
261
|
-
err,
|
|
262
|
-
{ checkpointNumber: targetCheckpoint },
|
|
263
|
-
);
|
|
261
|
+
const parentTotalMsgCount = (await fork.getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE)).size;
|
|
262
|
+
const parentBucket = await this.l1ToL2MessageSource.getInboxBucketByTotalMsgCount(parentTotalMsgCount);
|
|
263
|
+
if (parentBucket === undefined) {
|
|
264
|
+
this.log.debug(`Inbox bucket at message total ${parentTotalMsgCount} not synced; simulating against the tip`, {
|
|
265
|
+
parentTotalMsgCount,
|
|
266
|
+
});
|
|
267
|
+
return;
|
|
264
268
|
}
|
|
265
|
-
|
|
269
|
+
|
|
270
|
+
// Origin of the per-checkpoint cap: the total consumed as of the checkpoint's parent. A block extending an
|
|
271
|
+
// in-progress checkpoint reads it off that checkpoint's parent block; a block opening one starts from the tip.
|
|
272
|
+
const checkpointStartTotalMsgCount =
|
|
273
|
+
opts.checkpointStartBlock === undefined
|
|
274
|
+
? parentTotalMsgCount
|
|
275
|
+
: await this.getConsumedMessageTotal(opts.checkpointStartBlock);
|
|
276
|
+
if (checkpointStartTotalMsgCount === undefined) {
|
|
277
|
+
this.log.debug(`Block ${opts.checkpointStartBlock} has no header on this node; simulating against the tip`);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const l1Constants = this.epochCache.getL1Constants();
|
|
282
|
+
const selection = await selectInboxBucketForBlock({
|
|
283
|
+
messageSource: this.l1ToL2MessageSource,
|
|
284
|
+
now: BigInt(Math.floor(this.dateProvider.now() / 1000)),
|
|
285
|
+
minBucketAgeSeconds: BigInt(l1Constants.ethereumSlotDuration),
|
|
286
|
+
parent: { seq: parentBucket.seq, totalMsgCount: parentBucket.totalMsgCount },
|
|
287
|
+
checkpointStartTotalMsgCount,
|
|
288
|
+
perBlockCap: MAX_L1_TO_L2_MSGS_PER_BLOCK,
|
|
289
|
+
perCheckpointCap: MAX_L1_TO_L2_MSGS_PER_CHECKPOINT,
|
|
290
|
+
isLastBlock: false,
|
|
291
|
+
cutoffTimestamp: getInboxCutoffTimestamp(opts.slotNumber, l1Constants),
|
|
292
|
+
});
|
|
293
|
+
if (!selection.consume || selection.bundle.length === 0) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
await appendL1ToL2MessagesToTree(fork, selection.bundle);
|
|
298
|
+
this.log.debug(`Appended ${selection.bundle.length} predicted L1-to-L2 messages to the simulation fork`, {
|
|
299
|
+
bucketSeq: selection.bucket.seq,
|
|
300
|
+
messageCount: selection.bundle.length,
|
|
301
|
+
});
|
|
302
|
+
} catch (err) {
|
|
303
|
+
this.log.verbose(`Could not predict the next block's L1-to-L2 messages, simulating against the tip: ${err}`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/** Cumulative Inbox message total consumed as of `blockNumber`, i.e. its L1-to-L2 message tree leaf count. */
|
|
308
|
+
private async getConsumedMessageTotal(blockNumber: BlockNumber): Promise<bigint | undefined> {
|
|
309
|
+
if (blockNumber === BlockNumber.ZERO) {
|
|
310
|
+
return 0n;
|
|
266
311
|
}
|
|
312
|
+
const block = await this.blockSource.getBlockData({ number: blockNumber });
|
|
313
|
+
return block === undefined ? undefined : BigInt(block.header.state.l1ToL2MessageTree.nextAvailableLeafIndex);
|
|
267
314
|
}
|
|
268
315
|
|
|
269
316
|
/**
|
|
270
317
|
* Continues an in-progress checkpoint: the next block extends the checkpoint the latest proposed
|
|
271
318
|
* block belongs to. Every block in a checkpoint shares the same `CheckpointGlobalVariables`, so the
|
|
272
319
|
* next block's globals are the latest proposed block's globals with only the block number bumped —
|
|
273
|
-
* including the proposer's real coinbase/feeRecipient. No L1 reads
|
|
274
|
-
* happen here.
|
|
320
|
+
* including the proposer's real coinbase/feeRecipient. No L1 reads happen here.
|
|
275
321
|
*
|
|
276
322
|
* A missing header means the archiver reported a proposed tip via `getL2Tips` but no longer has its
|
|
277
323
|
* data (a torn snapshot). We throw a transient/retryable error rather than treating the next block as
|
|
278
|
-
* opening a new checkpoint
|
|
279
|
-
* L1-to-L2 messages, so inserting the next checkpoint's messages would append them a second time.
|
|
324
|
+
* opening a new checkpoint, whose globals would be built for the wrong slot.
|
|
280
325
|
*/
|
|
281
326
|
private async copyGlobalVariablesFromLatestProposedBlock(
|
|
282
327
|
latestBlockNumber: BlockNumber,
|
|
@@ -298,19 +343,14 @@ export class NodePublicCallsSimulator {
|
|
|
298
343
|
* sequencer applies so the simulated mana min fee matches what the sequencer will write into the
|
|
299
344
|
* block header. Coinbase and fee recipient stay zero (we cannot know the future proposer's payout
|
|
300
345
|
* addresses), unlike continuing an in-progress checkpoint which inherits the real ones from the
|
|
301
|
-
* proposed header.
|
|
302
|
-
* messages into the fork.
|
|
346
|
+
* proposed header.
|
|
303
347
|
*/
|
|
304
348
|
private async buildGlobalVariablesForNewCheckpoint(
|
|
305
349
|
l2Tips: L2Tips,
|
|
306
350
|
proposedCheckpointData: ProposedCheckpointData | undefined,
|
|
307
351
|
blockNumber: BlockNumber,
|
|
308
|
-
): Promise<{ globalVariables: GlobalVariables
|
|
352
|
+
): Promise<{ globalVariables: GlobalVariables }> {
|
|
309
353
|
const checkpointedCheckpointNumber = l2Tips.checkpointed.checkpoint.number;
|
|
310
|
-
// The new checkpoint sits on top of the proposed one when pipelining, otherwise on the
|
|
311
|
-
// checkpointed tip. The target slot and the overrides plan both derive from the single
|
|
312
|
-
// `proposedCheckpointData` read, so they cannot disagree about the proposed parent.
|
|
313
|
-
const proposedCheckpointNumber = proposedCheckpointData?.checkpointNumber ?? checkpointedCheckpointNumber;
|
|
314
354
|
|
|
315
355
|
const targetSlot = this.computeTargetSlot(proposedCheckpointData);
|
|
316
356
|
const plan = await this.buildSimulationOverridesPlan(proposedCheckpointData, checkpointedCheckpointNumber);
|
|
@@ -324,7 +364,6 @@ export class NodePublicCallsSimulator {
|
|
|
324
364
|
|
|
325
365
|
return {
|
|
326
366
|
globalVariables: GlobalVariables.from({ blockNumber, ...checkpointGlobalVariables }),
|
|
327
|
-
targetCheckpoint: CheckpointNumber(proposedCheckpointNumber + 1),
|
|
328
367
|
};
|
|
329
368
|
}
|
|
330
369
|
|
|
@@ -1,9 +1,20 @@
|
|
|
1
|
-
import type { NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server';
|
|
1
|
+
import type { NamespacedApiHandlers, StatusCheckFn } from '@aztec/foundation/json-rpc/server';
|
|
2
2
|
import { AztecNodeAdminApiSchema, AztecNodeApiSchema, AztecNodeDebugApiSchema } from '@aztec/stdlib/interfaces/client';
|
|
3
|
-
import { P2PApiSchema } from '@aztec/stdlib/interfaces/server';
|
|
3
|
+
import { type P2PApi, P2PApiSchema } from '@aztec/stdlib/interfaces/server';
|
|
4
4
|
|
|
5
5
|
import type { AztecNodeService } from './server.js';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Health check for the p2p component: reports whether p2p is enabled and how many peers are connected, and fails
|
|
9
|
+
* when p2p is enabled but connected to fewer peers than the given minimum. A minimum of zero never fails.
|
|
10
|
+
*/
|
|
11
|
+
function makeP2PHealthCheck(p2p: P2PApi, minPeers: number): StatusCheckFn {
|
|
12
|
+
return async () => {
|
|
13
|
+
const { enabled, connectedPeers } = await p2p.getP2PConnectivity();
|
|
14
|
+
return { healthy: !enabled || connectedPeers >= minPeers, details: { enabled, connectedPeers } };
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
7
18
|
/**
|
|
8
19
|
* Registers the Aztec node RPC handlers (`aztec_*`, `aztecAdmin_*`, and optionally `aztecDebug_*`), along with the
|
|
9
20
|
* legacy pre-v5 namespaces (`node_*`, `nodeAdmin_*`, `nodeDebug_*`, `p2p_*`) for backwards compatibility.
|
|
@@ -13,11 +24,12 @@ export function registerAztecNodeRpcHandlers(
|
|
|
13
24
|
node: AztecNodeService,
|
|
14
25
|
services: NamespacedApiHandlers,
|
|
15
26
|
adminServices?: NamespacedApiHandlers,
|
|
16
|
-
options: { debug?: boolean } = {},
|
|
27
|
+
options: { debug?: boolean; p2pHealthMinPeers?: number } = {},
|
|
17
28
|
): void {
|
|
29
|
+
const p2p = node.getP2P();
|
|
18
30
|
services.aztec = [node, AztecNodeApiSchema];
|
|
19
31
|
services.node = services.aztec;
|
|
20
|
-
services.p2p = [
|
|
32
|
+
services.p2p = [p2p, P2PApiSchema, makeP2PHealthCheck(p2p, options.p2pHealthMinPeers ?? 0)];
|
|
21
33
|
if (adminServices) {
|
|
22
34
|
adminServices.aztecAdmin = [node, AztecNodeAdminApiSchema];
|
|
23
35
|
adminServices.nodeAdmin = adminServices.aztecAdmin;
|
package/src/aztec-node/server.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
import { compactArray, pick, unique } from '@aztec/foundation/collection';
|
|
17
17
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
18
18
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
19
|
+
import { first } from '@aztec/foundation/iterable';
|
|
19
20
|
import { BadRequestError } from '@aztec/foundation/json-rpc';
|
|
20
21
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
21
22
|
import { retryUntil } from '@aztec/foundation/retry';
|
|
@@ -463,11 +464,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb
|
|
|
463
464
|
}
|
|
464
465
|
|
|
465
466
|
public async getMaxPriorityFees(): Promise<GasFees> {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
return GasFees.from({ feePerDaGas: 0n, feePerL2Gas: 0n });
|
|
467
|
+
const tx = await first(this.p2pClient.iteratePendingTxs({ includeProof: false }));
|
|
468
|
+
return tx ? tx.getGasSettings().maxPriorityFeesPerGas : GasFees.from({ feePerDaGas: 0n, feePerL2Gas: 0n });
|
|
471
469
|
}
|
|
472
470
|
|
|
473
471
|
/**
|
|
@@ -531,6 +529,13 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb
|
|
|
531
529
|
const timer = new Timer();
|
|
532
530
|
const txHash = tx.getTxHash().toString();
|
|
533
531
|
|
|
532
|
+
const connectivity = await this.p2pClient.getP2PConnectivity();
|
|
533
|
+
if (connectivity.enabled && connectivity.connectedPeers === 0) {
|
|
534
|
+
this.metrics.receivedTx(timer.ms(), false);
|
|
535
|
+
this.log.warn(`Rejecting tx ${txHash}: node has no connected peers`, { txHash });
|
|
536
|
+
throw new Error('Cannot accept tx: node has no connected peers to propagate it');
|
|
537
|
+
}
|
|
538
|
+
|
|
534
539
|
const valid = await this.isValidTx(tx);
|
|
535
540
|
if (valid.result !== 'valid') {
|
|
536
541
|
const reason = valid.reason.join(', ');
|
|
@@ -674,8 +679,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb
|
|
|
674
679
|
return this.worldStateQueries.getL1ToL2MessageMembershipWitness(referenceBlock, l1ToL2Message);
|
|
675
680
|
}
|
|
676
681
|
|
|
677
|
-
public
|
|
678
|
-
return this.worldStateQueries.
|
|
682
|
+
public getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise<bigint | undefined> {
|
|
683
|
+
return this.worldStateQueries.getL1ToL2MessageIndex(l1ToL2Message);
|
|
679
684
|
}
|
|
680
685
|
|
|
681
686
|
/**
|
package/src/bin/index.ts
CHANGED
|
@@ -5,7 +5,12 @@ import {
|
|
|
5
5
|
startHttpRpcServer,
|
|
6
6
|
} from '@aztec/foundation/json-rpc/server';
|
|
7
7
|
import { createLogger } from '@aztec/foundation/log';
|
|
8
|
-
import {
|
|
8
|
+
import { getRpcCorsAllowedOrigins } from '@aztec/stdlib/config';
|
|
9
|
+
import {
|
|
10
|
+
getOtelJsonRpcDiagnosticsMiddleware,
|
|
11
|
+
getOtelJsonRpcPropagationMiddleware,
|
|
12
|
+
getOtelJsonRpcServerMetricsMiddleware,
|
|
13
|
+
} from '@aztec/telemetry-client';
|
|
9
14
|
|
|
10
15
|
import {
|
|
11
16
|
type AztecNodeConfig,
|
|
@@ -21,9 +26,7 @@ const logger = createLogger('node');
|
|
|
21
26
|
/**
|
|
22
27
|
* Creates the node from provided config
|
|
23
28
|
*/
|
|
24
|
-
async function createAndDeployAztecNode() {
|
|
25
|
-
const aztecNodeConfig: AztecNodeConfig = { ...getConfigEnvVars() };
|
|
26
|
-
|
|
29
|
+
async function createAndDeployAztecNode(aztecNodeConfig: AztecNodeConfig) {
|
|
27
30
|
return await createAztecNodeService(aztecNodeConfig);
|
|
28
31
|
}
|
|
29
32
|
|
|
@@ -33,7 +36,8 @@ async function createAndDeployAztecNode() {
|
|
|
33
36
|
async function main() {
|
|
34
37
|
logger.info(`Setting up Aztec Node...`);
|
|
35
38
|
|
|
36
|
-
const
|
|
39
|
+
const aztecNodeConfig: AztecNodeConfig = { ...getConfigEnvVars() };
|
|
40
|
+
const aztecNode = await createAndDeployAztecNode(aztecNodeConfig);
|
|
37
41
|
|
|
38
42
|
const shutdown = async () => {
|
|
39
43
|
logger.info('Shutting down...');
|
|
@@ -47,11 +51,23 @@ async function main() {
|
|
|
47
51
|
process.once('SIGTERM', shutdown);
|
|
48
52
|
|
|
49
53
|
const services: NamespacedApiHandlers = {};
|
|
50
|
-
registerAztecNodeRpcHandlers(aztecNode, services
|
|
54
|
+
registerAztecNodeRpcHandlers(aztecNode, services, undefined, {
|
|
55
|
+
p2pHealthMinPeers: aztecNodeConfig.p2pHealthMinPeers,
|
|
56
|
+
});
|
|
51
57
|
const rpcServer = createNamespacedSafeJsonRpcServer(services, {
|
|
52
|
-
|
|
58
|
+
diagnostic: getOtelJsonRpcDiagnosticsMiddleware(),
|
|
59
|
+
middlewares: [getOtelJsonRpcServerMetricsMiddleware(), getOtelJsonRpcPropagationMiddleware()],
|
|
60
|
+
maxBatchSize: aztecNodeConfig.rpcMaxBatchSize,
|
|
61
|
+
maxBodySizeBytes: aztecNodeConfig.rpcMaxBodySize,
|
|
62
|
+
corsAllowedHeaders: aztecNodeConfig.rpcCorsAllowedHeaders,
|
|
63
|
+
corsAllowedOrigins: getRpcCorsAllowedOrigins(aztecNodeConfig),
|
|
64
|
+
});
|
|
65
|
+
await startHttpRpcServer(rpcServer, {
|
|
66
|
+
port: +AZTEC_NODE_PORT,
|
|
67
|
+
apiPrefix: API_PREFIX,
|
|
68
|
+
keepAliveTimeoutMs: aztecNodeConfig.rpcHttpKeepAliveTimeoutMs,
|
|
69
|
+
headersTimeoutMs: aztecNodeConfig.rpcHttpHeadersTimeoutMs,
|
|
53
70
|
});
|
|
54
|
-
await startHttpRpcServer(rpcServer, { port: +AZTEC_NODE_PORT, apiPrefix: API_PREFIX });
|
|
55
71
|
logger.info(`Aztec Node JSON-RPC Server listening on port ${AZTEC_NODE_PORT}`);
|
|
56
72
|
}
|
|
57
73
|
|