@aztec/sequencer-client 0.54.0 → 0.55.1
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/client/sequencer-client.d.ts +1 -2
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +1 -1
- package/dest/global_variable_builder/global_builder.d.ts +2 -1
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/global_variable_builder/global_builder.js +1 -1
- package/dest/index.d.ts +0 -4
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -5
- package/dest/publisher/l1-publisher.d.ts +6 -8
- package/dest/publisher/l1-publisher.d.ts.map +1 -1
- package/dest/publisher/l1-publisher.js +27 -73
- package/dest/publisher/utils.d.ts +3 -0
- package/dest/publisher/utils.d.ts.map +1 -0
- package/dest/publisher/utils.js +12 -0
- package/dest/sequencer/sequencer.d.ts +3 -4
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +17 -20
- package/dest/tx_validator/tx_validator_factory.d.ts.map +1 -1
- package/dest/tx_validator/tx_validator_factory.js +3 -6
- package/package.json +19 -19
- package/src/client/sequencer-client.ts +1 -2
- package/src/global_variable_builder/global_builder.ts +2 -1
- package/src/index.ts +0 -4
- package/src/publisher/l1-publisher.ts +29 -80
- package/src/publisher/utils.ts +15 -0
- package/src/sequencer/sequencer.ts +20 -23
- package/src/tx_validator/tx_validator_factory.ts +2 -5
- package/dest/tx_validator/aggregate_tx_validator.d.ts +0 -7
- package/dest/tx_validator/aggregate_tx_validator.d.ts.map +0 -1
- package/dest/tx_validator/aggregate_tx_validator.js +0 -23
- package/dest/tx_validator/data_validator.d.ts +0 -6
- package/dest/tx_validator/data_validator.d.ts.map +0 -1
- package/dest/tx_validator/data_validator.js +0 -47
- package/dest/tx_validator/double_spend_validator.d.ts +0 -11
- package/dest/tx_validator/double_spend_validator.d.ts.map +0 -1
- package/dest/tx_validator/double_spend_validator.js +0 -50
- package/dest/tx_validator/metadata_validator.d.ts +0 -8
- package/dest/tx_validator/metadata_validator.d.ts.map +0 -1
- package/dest/tx_validator/metadata_validator.js +0 -50
- package/src/tx_validator/aggregate_tx_validator.ts +0 -24
- package/src/tx_validator/data_validator.ts +0 -61
- package/src/tx_validator/double_spend_validator.ts +0 -63
- package/src/tx_validator/metadata_validator.ts +0 -60
|
@@ -6,7 +6,10 @@ import {
|
|
|
6
6
|
type ProcessedTx,
|
|
7
7
|
Signature,
|
|
8
8
|
Tx,
|
|
9
|
+
type TxHash,
|
|
9
10
|
type TxValidator,
|
|
11
|
+
type WorldStateStatus,
|
|
12
|
+
type WorldStateSynchronizer,
|
|
10
13
|
} from '@aztec/circuit-types';
|
|
11
14
|
import { type AllowedElement, BlockProofError, PROVING_STATUS } from '@aztec/circuit-types/interfaces';
|
|
12
15
|
import { type L2BlockBuiltStats } from '@aztec/circuit-types/stats';
|
|
@@ -27,13 +30,11 @@ import { type P2P } from '@aztec/p2p';
|
|
|
27
30
|
import { type PublicProcessorFactory } from '@aztec/simulator';
|
|
28
31
|
import { Attributes, type TelemetryClient, type Tracer, trackSpan } from '@aztec/telemetry-client';
|
|
29
32
|
import { type ValidatorClient } from '@aztec/validator-client';
|
|
30
|
-
import { type WorldStateStatus, type WorldStateSynchronizer } from '@aztec/world-state';
|
|
31
|
-
|
|
32
|
-
import { BaseError, ContractFunctionRevertedError } from 'viem';
|
|
33
33
|
|
|
34
34
|
import { type BlockBuilderFactory } from '../block_builder/index.js';
|
|
35
35
|
import { type GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
|
|
36
36
|
import { type L1Publisher } from '../publisher/l1-publisher.js';
|
|
37
|
+
import { prettyLogVeimError } from '../publisher/utils.js';
|
|
37
38
|
import { type TxValidatorFactory } from '../tx_validator/tx_validator_factory.js';
|
|
38
39
|
import { type SequencerConfig } from './config.js';
|
|
39
40
|
import { SequencerMetrics } from './metrics.js';
|
|
@@ -310,17 +311,7 @@ export class Sequencer {
|
|
|
310
311
|
this.log.debug(`Can propose block ${proposalBlockNumber} at slot ${slot}`);
|
|
311
312
|
return slot;
|
|
312
313
|
} catch (err) {
|
|
313
|
-
|
|
314
|
-
const revertError = err.walk(err => err instanceof ContractFunctionRevertedError);
|
|
315
|
-
if (revertError instanceof ContractFunctionRevertedError) {
|
|
316
|
-
const errorName = revertError.data?.errorName ?? '';
|
|
317
|
-
const args =
|
|
318
|
-
revertError.metaMessages && revertError.metaMessages?.length > 1
|
|
319
|
-
? revertError.metaMessages[1].trimStart()
|
|
320
|
-
: '';
|
|
321
|
-
this.log.debug(`canProposeAtTime failed with "${errorName}${args}"`);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
314
|
+
prettyLogVeimError(err, this.log);
|
|
324
315
|
throw err;
|
|
325
316
|
}
|
|
326
317
|
}
|
|
@@ -490,11 +481,15 @@ export class Sequencer {
|
|
|
490
481
|
this.log.verbose(`Flushing completed`);
|
|
491
482
|
}
|
|
492
483
|
|
|
484
|
+
const txHashes = validTxs.map(tx => tx.getTxHash());
|
|
485
|
+
|
|
493
486
|
this.isFlushing = false;
|
|
494
|
-
|
|
487
|
+
this.log.verbose('Collecting attestations');
|
|
488
|
+
const attestations = await this.collectAttestations(block, txHashes);
|
|
489
|
+
this.log.verbose('Attestations collected');
|
|
495
490
|
|
|
496
491
|
try {
|
|
497
|
-
await this.publishL2Block(block, attestations);
|
|
492
|
+
await this.publishL2Block(block, attestations, txHashes);
|
|
498
493
|
this.metrics.recordPublishedBlock(workDuration);
|
|
499
494
|
this.log.info(
|
|
500
495
|
`Submitted rollup block ${block.number} with ${
|
|
@@ -512,11 +507,13 @@ export class Sequencer {
|
|
|
512
507
|
this.isFlushing = true;
|
|
513
508
|
}
|
|
514
509
|
|
|
515
|
-
protected async collectAttestations(block: L2Block): Promise<Signature[] | undefined> {
|
|
510
|
+
protected async collectAttestations(block: L2Block, txHashes: TxHash[]): Promise<Signature[] | undefined> {
|
|
516
511
|
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/7962): inefficient to have a round trip in here - this should be cached
|
|
517
512
|
const committee = await this.publisher.getCurrentEpochCommittee();
|
|
513
|
+
this.log.debug(`Attesting committee length ${committee.length}`);
|
|
518
514
|
|
|
519
515
|
if (committee.length === 0) {
|
|
516
|
+
this.log.debug(`Attesting committee length is 0, skipping`);
|
|
520
517
|
return undefined;
|
|
521
518
|
}
|
|
522
519
|
|
|
@@ -528,16 +525,16 @@ export class Sequencer {
|
|
|
528
525
|
|
|
529
526
|
const numberOfRequiredAttestations = Math.floor((committee.length * 2) / 3) + 1;
|
|
530
527
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
const proposal = await this.validatorClient.createBlockProposal(block.header, block.archive.root, []);
|
|
528
|
+
this.log.verbose('Creating block proposal');
|
|
529
|
+
const proposal = await this.validatorClient.createBlockProposal(block.header, block.archive.root, txHashes);
|
|
535
530
|
|
|
536
531
|
this.state = SequencerState.PUBLISHING_BLOCK_TO_PEERS;
|
|
532
|
+
this.log.verbose('Broadcasting block proposal to validators');
|
|
537
533
|
this.validatorClient.broadcastBlockProposal(proposal);
|
|
538
534
|
|
|
539
535
|
this.state = SequencerState.WAITING_FOR_ATTESTATIONS;
|
|
540
536
|
const attestations = await this.validatorClient.collectAttestations(proposal, numberOfRequiredAttestations);
|
|
537
|
+
this.log.verbose(`Collected attestations from validators, number of attestations: ${attestations.length}`);
|
|
541
538
|
|
|
542
539
|
// note: the smart contract requires that the signatures are provided in the order of the committee
|
|
543
540
|
return await orderAttestations(attestations, committee);
|
|
@@ -550,11 +547,11 @@ export class Sequencer {
|
|
|
550
547
|
@trackSpan('Sequencer.publishL2Block', block => ({
|
|
551
548
|
[Attributes.BLOCK_NUMBER]: block.number,
|
|
552
549
|
}))
|
|
553
|
-
protected async publishL2Block(block: L2Block, attestations?: Signature[]) {
|
|
550
|
+
protected async publishL2Block(block: L2Block, attestations?: Signature[], txHashes?: TxHash[]) {
|
|
554
551
|
// Publishes new block to the network and awaits the tx to be mined
|
|
555
552
|
this.state = SequencerState.PUBLISHING_BLOCK;
|
|
556
553
|
|
|
557
|
-
const publishedL2Block = await this.publisher.
|
|
554
|
+
const publishedL2Block = await this.publisher.proposeL2Block(block, attestations, txHashes);
|
|
558
555
|
if (publishedL2Block) {
|
|
559
556
|
this.lastPublishedBlock = block.number;
|
|
560
557
|
} else {
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { type AllowedElement, type ProcessedTx, type Tx, type TxValidator } from '@aztec/circuit-types';
|
|
2
2
|
import { type GlobalVariables } from '@aztec/circuits.js';
|
|
3
|
+
import { AggregateTxValidator, DataTxValidator, DoubleSpendTxValidator, MetadataTxValidator } from '@aztec/p2p';
|
|
3
4
|
import { FeeJuiceAddress } from '@aztec/protocol-contracts/fee-juice';
|
|
4
5
|
import { WorldStateDB, WorldStatePublicDB } from '@aztec/simulator';
|
|
5
6
|
import { type ContractDataSource } from '@aztec/types/contracts';
|
|
6
7
|
import { type MerkleTreeOperations } from '@aztec/world-state';
|
|
7
8
|
|
|
8
|
-
import { AggregateTxValidator } from './aggregate_tx_validator.js';
|
|
9
|
-
import { DataTxValidator } from './data_validator.js';
|
|
10
|
-
import { DoubleSpendTxValidator } from './double_spend_validator.js';
|
|
11
9
|
import { GasTxValidator } from './gas_validator.js';
|
|
12
|
-
import { MetadataTxValidator } from './metadata_validator.js';
|
|
13
10
|
import { PhasesTxValidator } from './phases_validator.js';
|
|
14
11
|
|
|
15
12
|
export class TxValidatorFactory {
|
|
@@ -22,7 +19,7 @@ export class TxValidatorFactory {
|
|
|
22
19
|
validatorForNewTxs(globalVariables: GlobalVariables, setupAllowList: AllowedElement[]): TxValidator<Tx> {
|
|
23
20
|
return new AggregateTxValidator(
|
|
24
21
|
new DataTxValidator(),
|
|
25
|
-
new MetadataTxValidator(globalVariables),
|
|
22
|
+
new MetadataTxValidator(globalVariables.chainId, globalVariables.blockNumber),
|
|
26
23
|
new DoubleSpendTxValidator(new WorldStateDB(this.merkleTreeDb)),
|
|
27
24
|
new PhasesTxValidator(this.contractDataSource, setupAllowList),
|
|
28
25
|
new GasTxValidator(new WorldStatePublicDB(this.merkleTreeDb), FeeJuiceAddress, this.enforceFees),
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { type ProcessedTx, type Tx, type TxValidator } from '@aztec/circuit-types';
|
|
2
|
-
export declare class AggregateTxValidator<T extends Tx | ProcessedTx> implements TxValidator<T> {
|
|
3
|
-
#private;
|
|
4
|
-
constructor(...validators: TxValidator<T>[]);
|
|
5
|
-
validateTxs(txs: T[]): Promise<[validTxs: T[], invalidTxs: T[]]>;
|
|
6
|
-
}
|
|
7
|
-
//# sourceMappingURL=aggregate_tx_validator.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"aggregate_tx_validator.d.ts","sourceRoot":"","sources":["../../src/tx_validator/aggregate_tx_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnF,qBAAa,oBAAoB,CAAC,CAAC,SAAS,EAAE,GAAG,WAAW,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;;gBAEzE,GAAG,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE;IAQrC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;CAWvE"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
var _AggregateTxValidator_validators;
|
|
2
|
-
import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
|
|
3
|
-
export class AggregateTxValidator {
|
|
4
|
-
constructor(...validators) {
|
|
5
|
-
_AggregateTxValidator_validators.set(this, void 0);
|
|
6
|
-
if (validators.length === 0) {
|
|
7
|
-
throw new Error('At least one validator must be provided');
|
|
8
|
-
}
|
|
9
|
-
__classPrivateFieldSet(this, _AggregateTxValidator_validators, validators, "f");
|
|
10
|
-
}
|
|
11
|
-
async validateTxs(txs) {
|
|
12
|
-
const invalidTxs = [];
|
|
13
|
-
let txPool = txs;
|
|
14
|
-
for (const validator of __classPrivateFieldGet(this, _AggregateTxValidator_validators, "f")) {
|
|
15
|
-
const [valid, invalid] = await validator.validateTxs(txPool);
|
|
16
|
-
invalidTxs.push(...invalid);
|
|
17
|
-
txPool = valid;
|
|
18
|
-
}
|
|
19
|
-
return [txPool, invalidTxs];
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
_AggregateTxValidator_validators = new WeakMap();
|
|
23
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdncmVnYXRlX3R4X3ZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eF92YWxpZGF0b3IvYWdncmVnYXRlX3R4X3ZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLE1BQU0sT0FBTyxvQkFBb0I7SUFFL0IsWUFBWSxHQUFHLFVBQTRCO1FBRDNDLG1EQUE4QjtRQUU1QixJQUFJLFVBQVUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDNUIsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO1FBQzdELENBQUM7UUFFRCx1QkFBQSxJQUFJLG9DQUFlLFVBQVUsTUFBQSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxLQUFLLENBQUMsV0FBVyxDQUFDLEdBQVE7UUFDeEIsTUFBTSxVQUFVLEdBQVEsRUFBRSxDQUFDO1FBQzNCLElBQUksTUFBTSxHQUFHLEdBQUcsQ0FBQztRQUNqQixLQUFLLE1BQU0sU0FBUyxJQUFJLHVCQUFBLElBQUksd0NBQVksRUFBRSxDQUFDO1lBQ3pDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsTUFBTSxTQUFTLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzdELFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQztZQUM1QixNQUFNLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLENBQUM7UUFFRCxPQUFPLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQzlCLENBQUM7Q0FDRiJ9
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data_validator.d.ts","sourceRoot":"","sources":["../../src/tx_validator/data_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAG5D,qBAAa,eAAgB,YAAW,WAAW,CAAC,EAAE,CAAC;;IAGrD,WAAW,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;CAsDpE"}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
var _DataTxValidator_instances, _DataTxValidator_log, _DataTxValidator_hasCorrectExecutionRequests;
|
|
2
|
-
import { __classPrivateFieldGet } from "tslib";
|
|
3
|
-
import { Tx } from '@aztec/circuit-types';
|
|
4
|
-
import { createDebugLogger } from '@aztec/foundation/log';
|
|
5
|
-
export class DataTxValidator {
|
|
6
|
-
constructor() {
|
|
7
|
-
_DataTxValidator_instances.add(this);
|
|
8
|
-
_DataTxValidator_log.set(this, createDebugLogger('aztec:sequencer:tx_validator:tx_data'));
|
|
9
|
-
// TODO: Check logs.
|
|
10
|
-
}
|
|
11
|
-
validateTxs(txs) {
|
|
12
|
-
const validTxs = [];
|
|
13
|
-
const invalidTxs = [];
|
|
14
|
-
for (const tx of txs) {
|
|
15
|
-
if (!__classPrivateFieldGet(this, _DataTxValidator_instances, "m", _DataTxValidator_hasCorrectExecutionRequests).call(this, tx)) {
|
|
16
|
-
invalidTxs.push(tx);
|
|
17
|
-
continue;
|
|
18
|
-
}
|
|
19
|
-
validTxs.push(tx);
|
|
20
|
-
}
|
|
21
|
-
return Promise.resolve([validTxs, invalidTxs]);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
_DataTxValidator_log = new WeakMap(), _DataTxValidator_instances = new WeakSet(), _DataTxValidator_hasCorrectExecutionRequests = function _DataTxValidator_hasCorrectExecutionRequests(tx) {
|
|
25
|
-
const callRequests = [
|
|
26
|
-
...tx.data.getRevertiblePublicCallRequests(),
|
|
27
|
-
...tx.data.getNonRevertiblePublicCallRequests(),
|
|
28
|
-
];
|
|
29
|
-
if (callRequests.length !== tx.enqueuedPublicFunctionCalls.length) {
|
|
30
|
-
__classPrivateFieldGet(this, _DataTxValidator_log, "f").warn(`Rejecting tx ${Tx.getHash(tx)} because of mismatch number of execution requests for public calls. Expected ${callRequests.length}. Got ${tx.enqueuedPublicFunctionCalls.length}.`);
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
const invalidExecutionRequestIndex = tx.enqueuedPublicFunctionCalls.findIndex((execRequest, i) => !execRequest.isForCallRequest(callRequests[i]));
|
|
34
|
-
if (invalidExecutionRequestIndex !== -1) {
|
|
35
|
-
__classPrivateFieldGet(this, _DataTxValidator_log, "f").warn(`Rejecting tx ${Tx.getHash(tx)} because of incorrect execution requests for public call at index ${invalidExecutionRequestIndex}.`);
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
const teardownCallRequest = tx.data.getTeardownPublicCallRequest();
|
|
39
|
-
const isInvalidTeardownExecutionRequest = (!teardownCallRequest && !tx.publicTeardownFunctionCall.isEmpty()) ||
|
|
40
|
-
(teardownCallRequest && !tx.publicTeardownFunctionCall.isForCallRequest(teardownCallRequest));
|
|
41
|
-
if (isInvalidTeardownExecutionRequest) {
|
|
42
|
-
__classPrivateFieldGet(this, _DataTxValidator_log, "f").warn(`Rejecting tx ${Tx.getHash(tx)} because of incorrect teardown execution requests.`);
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
return true;
|
|
46
|
-
};
|
|
47
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YV92YWxpZGF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHhfdmFsaWRhdG9yL2RhdGFfdmFsaWRhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsT0FBTyxFQUFFLEVBQUUsRUFBb0IsTUFBTSxzQkFBc0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUUxRCxNQUFNLE9BQU8sZUFBZTtJQUE1Qjs7UUFDRSwrQkFBTyxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxFQUFDO1FBdURqRSxvQkFBb0I7SUFDdEIsQ0FBQztJQXREQyxXQUFXLENBQUMsR0FBUztRQUNuQixNQUFNLFFBQVEsR0FBUyxFQUFFLENBQUM7UUFDMUIsTUFBTSxVQUFVLEdBQVMsRUFBRSxDQUFDO1FBQzVCLEtBQUssTUFBTSxFQUFFLElBQUksR0FBRyxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLHVCQUFBLElBQUksZ0ZBQTZCLE1BQWpDLElBQUksRUFBOEIsRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFDM0MsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDcEIsU0FBUztZQUNYLENBQUM7WUFFRCxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3BCLENBQUM7UUFFRCxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQztJQUNqRCxDQUFDO0NBeUNGO3VMQXZDOEIsRUFBTTtJQUNqQyxNQUFNLFlBQVksR0FBRztRQUNuQixHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsK0JBQStCLEVBQUU7UUFDNUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxFQUFFO0tBQ2hELENBQUM7SUFDRixJQUFJLFlBQVksQ0FBQyxNQUFNLEtBQUssRUFBRSxDQUFDLDJCQUEyQixDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2xFLHVCQUFBLElBQUksNEJBQUssQ0FBQyxJQUFJLENBQ1osZ0JBQWdCLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLGdGQUM1QixZQUFZLENBQUMsTUFDZixTQUFTLEVBQUUsQ0FBQywyQkFBMkIsQ0FBQyxNQUFNLEdBQUcsQ0FDbEQsQ0FBQztRQUNGLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELE1BQU0sNEJBQTRCLEdBQUcsRUFBRSxDQUFDLDJCQUEyQixDQUFDLFNBQVMsQ0FDM0UsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDbkUsQ0FBQztJQUNGLElBQUksNEJBQTRCLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN4Qyx1QkFBQSxJQUFJLDRCQUFLLENBQUMsSUFBSSxDQUNaLGdCQUFnQixFQUFFLENBQUMsT0FBTyxDQUN4QixFQUFFLENBQ0gscUVBQXFFLDRCQUE0QixHQUFHLENBQ3RHLENBQUM7UUFDRixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxNQUFNLG1CQUFtQixHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQztJQUNuRSxNQUFNLGlDQUFpQyxHQUNyQyxDQUFDLENBQUMsbUJBQW1CLElBQUksQ0FBQyxFQUFFLENBQUMsMEJBQTBCLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDbEUsQ0FBQyxtQkFBbUIsSUFBSSxDQUFDLEVBQUUsQ0FBQywwQkFBMEIsQ0FBQyxnQkFBZ0IsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUM7SUFDaEcsSUFBSSxpQ0FBaUMsRUFBRSxDQUFDO1FBQ3RDLHVCQUFBLElBQUksNEJBQUssQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLG9EQUFvRCxDQUFDLENBQUM7UUFDbkcsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIn0=
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { type AnyTx, type TxValidator } from '@aztec/circuit-types';
|
|
2
|
-
import { Fr } from '@aztec/circuits.js';
|
|
3
|
-
export interface NullifierSource {
|
|
4
|
-
getNullifierIndex: (nullifier: Fr) => Promise<bigint | undefined>;
|
|
5
|
-
}
|
|
6
|
-
export declare class DoubleSpendTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
7
|
-
#private;
|
|
8
|
-
constructor(nullifierSource: NullifierSource);
|
|
9
|
-
validateTxs(txs: T[]): Promise<[validTxs: T[], invalidTxs: T[]]>;
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=double_spend_validator.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"double_spend_validator.d.ts","sourceRoot":"","sources":["../../src/tx_validator/double_spend_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAM,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAGxC,MAAM,WAAW,eAAe;IAC9B,iBAAiB,EAAE,CAAC,SAAS,EAAE,EAAE,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACnE;AAED,qBAAa,sBAAsB,CAAC,CAAC,SAAS,KAAK,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;;gBAIhE,eAAe,EAAE,eAAe;IAItC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;CA8CvE"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
var _DoubleSpendTxValidator_instances, _DoubleSpendTxValidator_log, _DoubleSpendTxValidator_nullifierSource, _DoubleSpendTxValidator_uniqueNullifiers;
|
|
2
|
-
import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
|
|
3
|
-
import { Tx } from '@aztec/circuit-types';
|
|
4
|
-
import { Fr } from '@aztec/circuits.js';
|
|
5
|
-
import { createDebugLogger } from '@aztec/foundation/log';
|
|
6
|
-
export class DoubleSpendTxValidator {
|
|
7
|
-
constructor(nullifierSource) {
|
|
8
|
-
_DoubleSpendTxValidator_instances.add(this);
|
|
9
|
-
_DoubleSpendTxValidator_log.set(this, createDebugLogger('aztec:sequencer:tx_validator:tx_double_spend'));
|
|
10
|
-
_DoubleSpendTxValidator_nullifierSource.set(this, void 0);
|
|
11
|
-
__classPrivateFieldSet(this, _DoubleSpendTxValidator_nullifierSource, nullifierSource, "f");
|
|
12
|
-
}
|
|
13
|
-
async validateTxs(txs) {
|
|
14
|
-
const validTxs = [];
|
|
15
|
-
const invalidTxs = [];
|
|
16
|
-
const thisBlockNullifiers = new Set();
|
|
17
|
-
for (const tx of txs) {
|
|
18
|
-
if (!(await __classPrivateFieldGet(this, _DoubleSpendTxValidator_instances, "m", _DoubleSpendTxValidator_uniqueNullifiers).call(this, tx, thisBlockNullifiers))) {
|
|
19
|
-
invalidTxs.push(tx);
|
|
20
|
-
continue;
|
|
21
|
-
}
|
|
22
|
-
validTxs.push(tx);
|
|
23
|
-
}
|
|
24
|
-
return [validTxs, invalidTxs];
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
_DoubleSpendTxValidator_log = new WeakMap(), _DoubleSpendTxValidator_nullifierSource = new WeakMap(), _DoubleSpendTxValidator_instances = new WeakSet(), _DoubleSpendTxValidator_uniqueNullifiers = async function _DoubleSpendTxValidator_uniqueNullifiers(tx, thisBlockNullifiers) {
|
|
28
|
-
const nullifiers = tx.data.getNonEmptyNullifiers().map(x => x.toBigInt());
|
|
29
|
-
// Ditch this tx if it has repeated nullifiers
|
|
30
|
-
const uniqueNullifiers = new Set(nullifiers);
|
|
31
|
-
if (uniqueNullifiers.size !== nullifiers.length) {
|
|
32
|
-
__classPrivateFieldGet(this, _DoubleSpendTxValidator_log, "f").warn(`Rejecting tx ${Tx.getHash(tx)} for emitting duplicate nullifiers`);
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
for (const nullifier of nullifiers) {
|
|
36
|
-
if (thisBlockNullifiers.has(nullifier)) {
|
|
37
|
-
__classPrivateFieldGet(this, _DoubleSpendTxValidator_log, "f").warn(`Rejecting tx ${Tx.getHash(tx)} for repeating a nullifier in the same block`);
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
40
|
-
thisBlockNullifiers.add(nullifier);
|
|
41
|
-
}
|
|
42
|
-
const nullifierIndexes = await Promise.all(nullifiers.map(n => __classPrivateFieldGet(this, _DoubleSpendTxValidator_nullifierSource, "f").getNullifierIndex(new Fr(n))));
|
|
43
|
-
const hasDuplicates = nullifierIndexes.some(index => index !== undefined);
|
|
44
|
-
if (hasDuplicates) {
|
|
45
|
-
__classPrivateFieldGet(this, _DoubleSpendTxValidator_log, "f").warn(`Rejecting tx ${Tx.getHash(tx)} for repeating nullifiers present in state trees`);
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
return true;
|
|
49
|
-
};
|
|
50
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG91YmxlX3NwZW5kX3ZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eF92YWxpZGF0b3IvZG91YmxlX3NwZW5kX3ZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE9BQU8sRUFBYyxFQUFFLEVBQW9CLE1BQU0sc0JBQXNCLENBQUM7QUFDeEUsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3hDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBTTFELE1BQU0sT0FBTyxzQkFBc0I7SUFJakMsWUFBWSxlQUFnQzs7UUFINUMsc0NBQU8saUJBQWlCLENBQUMsOENBQThDLENBQUMsRUFBQztRQUN6RSwwREFBa0M7UUFHaEMsdUJBQUEsSUFBSSwyQ0FBb0IsZUFBZSxNQUFBLENBQUM7SUFDMUMsQ0FBQztJQUVELEtBQUssQ0FBQyxXQUFXLENBQUMsR0FBUTtRQUN4QixNQUFNLFFBQVEsR0FBUSxFQUFFLENBQUM7UUFDekIsTUFBTSxVQUFVLEdBQVEsRUFBRSxDQUFDO1FBQzNCLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztRQUU5QyxLQUFLLE1BQU0sRUFBRSxJQUFJLEdBQUcsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxDQUFDLE1BQU0sdUJBQUEsSUFBSSxtRkFBa0IsTUFBdEIsSUFBSSxFQUFtQixFQUFFLEVBQUUsbUJBQW1CLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQzdELFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3BCLFNBQVM7WUFDWCxDQUFDO1lBRUQsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwQixDQUFDO1FBRUQsT0FBTyxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNoQyxDQUFDO0NBK0JGO29NQTdCQyxLQUFLLG1EQUFtQixFQUFTLEVBQUUsbUJBQWdDO0lBQ2pFLE1BQU0sVUFBVSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUUxRSw4Q0FBOEM7SUFDOUMsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUM3QyxJQUFJLGdCQUFnQixDQUFDLElBQUksS0FBSyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDaEQsdUJBQUEsSUFBSSxtQ0FBSyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsb0NBQW9DLENBQUMsQ0FBQztRQUNuRixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxLQUFLLE1BQU0sU0FBUyxJQUFJLFVBQVUsRUFBRSxDQUFDO1FBQ25DLElBQUksbUJBQW1CLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDdkMsdUJBQUEsSUFBSSxtQ0FBSyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsOENBQThDLENBQUMsQ0FBQztZQUM3RixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFFRCxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVELE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyx1QkFBQSxJQUFJLCtDQUFpQixDQUFDLGlCQUFpQixDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRXBILE1BQU0sYUFBYSxHQUFHLGdCQUFnQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQztJQUMxRSxJQUFJLGFBQWEsRUFBRSxDQUFDO1FBQ2xCLHVCQUFBLElBQUksbUNBQUssQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLGtEQUFrRCxDQUFDLENBQUM7UUFDakcsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIn0=
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { type AnyTx, type TxValidator } from '@aztec/circuit-types';
|
|
2
|
-
import { type GlobalVariables } from '@aztec/circuits.js';
|
|
3
|
-
export declare class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
4
|
-
#private;
|
|
5
|
-
constructor(globalVariables: GlobalVariables);
|
|
6
|
-
validateTxs(txs: T[]): Promise<[validTxs: T[], invalidTxs: T[]]>;
|
|
7
|
-
}
|
|
8
|
-
//# sourceMappingURL=metadata_validator.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadata_validator.d.ts","sourceRoot":"","sources":["../../src/tx_validator/metadata_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAM,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D,qBAAa,mBAAmB,CAAC,CAAC,SAAS,KAAK,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;;gBAI7D,eAAe,EAAE,eAAe;IAI5C,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;CA+CjE"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
var _MetadataTxValidator_instances, _MetadataTxValidator_log, _MetadataTxValidator_globalVariables, _MetadataTxValidator_hasCorrectChainId, _MetadataTxValidator_isValidForBlockNumber;
|
|
2
|
-
import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
|
|
3
|
-
import { Tx } from '@aztec/circuit-types';
|
|
4
|
-
import { createDebugLogger } from '@aztec/foundation/log';
|
|
5
|
-
export class MetadataTxValidator {
|
|
6
|
-
constructor(globalVariables) {
|
|
7
|
-
_MetadataTxValidator_instances.add(this);
|
|
8
|
-
_MetadataTxValidator_log.set(this, createDebugLogger('aztec:sequencer:tx_validator:tx_metadata'));
|
|
9
|
-
_MetadataTxValidator_globalVariables.set(this, void 0);
|
|
10
|
-
__classPrivateFieldSet(this, _MetadataTxValidator_globalVariables, globalVariables, "f");
|
|
11
|
-
}
|
|
12
|
-
validateTxs(txs) {
|
|
13
|
-
const validTxs = [];
|
|
14
|
-
const invalidTxs = [];
|
|
15
|
-
for (const tx of txs) {
|
|
16
|
-
if (!__classPrivateFieldGet(this, _MetadataTxValidator_instances, "m", _MetadataTxValidator_hasCorrectChainId).call(this, tx)) {
|
|
17
|
-
invalidTxs.push(tx);
|
|
18
|
-
continue;
|
|
19
|
-
}
|
|
20
|
-
if (!__classPrivateFieldGet(this, _MetadataTxValidator_instances, "m", _MetadataTxValidator_isValidForBlockNumber).call(this, tx)) {
|
|
21
|
-
invalidTxs.push(tx);
|
|
22
|
-
continue;
|
|
23
|
-
}
|
|
24
|
-
validTxs.push(tx);
|
|
25
|
-
}
|
|
26
|
-
return Promise.resolve([validTxs, invalidTxs]);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
_MetadataTxValidator_log = new WeakMap(), _MetadataTxValidator_globalVariables = new WeakMap(), _MetadataTxValidator_instances = new WeakSet(), _MetadataTxValidator_hasCorrectChainId = function _MetadataTxValidator_hasCorrectChainId(tx) {
|
|
30
|
-
if (!tx.data.constants.txContext.chainId.equals(__classPrivateFieldGet(this, _MetadataTxValidator_globalVariables, "f").chainId)) {
|
|
31
|
-
__classPrivateFieldGet(this, _MetadataTxValidator_log, "f").warn(`Rejecting tx ${Tx.getHash(tx)} because of incorrect chain ${tx.data.constants.txContext.chainId.toNumber()} != ${__classPrivateFieldGet(this, _MetadataTxValidator_globalVariables, "f").chainId.toNumber()}`);
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
return true;
|
|
36
|
-
}
|
|
37
|
-
}, _MetadataTxValidator_isValidForBlockNumber = function _MetadataTxValidator_isValidForBlockNumber(tx) {
|
|
38
|
-
const target = tx instanceof Tx
|
|
39
|
-
? tx.data.forRollup?.rollupValidationRequests || tx.data.forPublic.validationRequests.forRollup
|
|
40
|
-
: tx.data.rollupValidationRequests;
|
|
41
|
-
const maxBlockNumber = target.maxBlockNumber;
|
|
42
|
-
if (maxBlockNumber.isSome && maxBlockNumber.value < __classPrivateFieldGet(this, _MetadataTxValidator_globalVariables, "f").blockNumber) {
|
|
43
|
-
__classPrivateFieldGet(this, _MetadataTxValidator_log, "f").warn(`Rejecting tx ${Tx.getHash(tx)} for low max block number`);
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0YWRhdGFfdmFsaWRhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3R4X3ZhbGlkYXRvci9tZXRhZGF0YV92YWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQWMsRUFBRSxFQUFvQixNQUFNLHNCQUFzQixDQUFDO0FBRXhFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRTFELE1BQU0sT0FBTyxtQkFBbUI7SUFJOUIsWUFBWSxlQUFnQzs7UUFINUMsbUNBQU8saUJBQWlCLENBQUMsMENBQTBDLENBQUMsRUFBQztRQUNyRSx1REFBa0M7UUFHaEMsdUJBQUEsSUFBSSx3Q0FBb0IsZUFBZSxNQUFBLENBQUM7SUFDMUMsQ0FBQztJQUVELFdBQVcsQ0FBQyxHQUFRO1FBQ2xCLE1BQU0sUUFBUSxHQUFRLEVBQUUsQ0FBQztRQUN6QixNQUFNLFVBQVUsR0FBUSxFQUFFLENBQUM7UUFDM0IsS0FBSyxNQUFNLEVBQUUsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUNyQixJQUFJLENBQUMsdUJBQUEsSUFBSSw4RUFBbUIsTUFBdkIsSUFBSSxFQUFvQixFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUNqQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNwQixTQUFTO1lBQ1gsQ0FBQztZQUVELElBQUksQ0FBQyx1QkFBQSxJQUFJLGtGQUF1QixNQUEzQixJQUFJLEVBQXdCLEVBQUUsQ0FBQyxFQUFFLENBQUM7Z0JBQ3JDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3BCLFNBQVM7WUFDWCxDQUFDO1lBRUQsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwQixDQUFDO1FBRUQsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUM7SUFDakQsQ0FBQztDQTZCRjt5T0EzQm9CLEVBQUs7SUFDdEIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLHVCQUFBLElBQUksNENBQWlCLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUMvRSx1QkFBQSxJQUFJLGdDQUFLLENBQUMsSUFBSSxDQUNaLGdCQUFnQixFQUFFLENBQUMsT0FBTyxDQUN4QixFQUFFLENBQ0gsK0JBQStCLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLE9BQU8sdUJBQUEsSUFBSSw0Q0FBaUIsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FDaEksQ0FBQztRQUNGLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztTQUFNLENBQUM7UUFDTixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7QUFDSCxDQUFDLG1HQUVzQixFQUFLO0lBQzFCLE1BQU0sTUFBTSxHQUNWLEVBQUUsWUFBWSxFQUFFO1FBQ2QsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLHdCQUF3QixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBVSxDQUFDLGtCQUFrQixDQUFDLFNBQVM7UUFDaEcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUM7SUFDdkMsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQztJQUU3QyxJQUFJLGNBQWMsQ0FBQyxNQUFNLElBQUksY0FBYyxDQUFDLEtBQUssR0FBRyx1QkFBQSxJQUFJLDRDQUFpQixDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3RGLHVCQUFBLElBQUksZ0NBQUssQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDMUUsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO1NBQU0sQ0FBQztRQUNOLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztBQUNILENBQUMifQ==
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { type ProcessedTx, type Tx, type TxValidator } from '@aztec/circuit-types';
|
|
2
|
-
|
|
3
|
-
export class AggregateTxValidator<T extends Tx | ProcessedTx> implements TxValidator<T> {
|
|
4
|
-
#validators: TxValidator<T>[];
|
|
5
|
-
constructor(...validators: TxValidator<T>[]) {
|
|
6
|
-
if (validators.length === 0) {
|
|
7
|
-
throw new Error('At least one validator must be provided');
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
this.#validators = validators;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
async validateTxs(txs: T[]): Promise<[validTxs: T[], invalidTxs: T[]]> {
|
|
14
|
-
const invalidTxs: T[] = [];
|
|
15
|
-
let txPool = txs;
|
|
16
|
-
for (const validator of this.#validators) {
|
|
17
|
-
const [valid, invalid] = await validator.validateTxs(txPool);
|
|
18
|
-
invalidTxs.push(...invalid);
|
|
19
|
-
txPool = valid;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return [txPool, invalidTxs];
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { Tx, type TxValidator } from '@aztec/circuit-types';
|
|
2
|
-
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
|
-
|
|
4
|
-
export class DataTxValidator implements TxValidator<Tx> {
|
|
5
|
-
#log = createDebugLogger('aztec:sequencer:tx_validator:tx_data');
|
|
6
|
-
|
|
7
|
-
validateTxs(txs: Tx[]): Promise<[validTxs: Tx[], invalidTxs: Tx[]]> {
|
|
8
|
-
const validTxs: Tx[] = [];
|
|
9
|
-
const invalidTxs: Tx[] = [];
|
|
10
|
-
for (const tx of txs) {
|
|
11
|
-
if (!this.#hasCorrectExecutionRequests(tx)) {
|
|
12
|
-
invalidTxs.push(tx);
|
|
13
|
-
continue;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
validTxs.push(tx);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return Promise.resolve([validTxs, invalidTxs]);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
#hasCorrectExecutionRequests(tx: Tx): boolean {
|
|
23
|
-
const callRequests = [
|
|
24
|
-
...tx.data.getRevertiblePublicCallRequests(),
|
|
25
|
-
...tx.data.getNonRevertiblePublicCallRequests(),
|
|
26
|
-
];
|
|
27
|
-
if (callRequests.length !== tx.enqueuedPublicFunctionCalls.length) {
|
|
28
|
-
this.#log.warn(
|
|
29
|
-
`Rejecting tx ${Tx.getHash(tx)} because of mismatch number of execution requests for public calls. Expected ${
|
|
30
|
-
callRequests.length
|
|
31
|
-
}. Got ${tx.enqueuedPublicFunctionCalls.length}.`,
|
|
32
|
-
);
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const invalidExecutionRequestIndex = tx.enqueuedPublicFunctionCalls.findIndex(
|
|
37
|
-
(execRequest, i) => !execRequest.isForCallRequest(callRequests[i]),
|
|
38
|
-
);
|
|
39
|
-
if (invalidExecutionRequestIndex !== -1) {
|
|
40
|
-
this.#log.warn(
|
|
41
|
-
`Rejecting tx ${Tx.getHash(
|
|
42
|
-
tx,
|
|
43
|
-
)} because of incorrect execution requests for public call at index ${invalidExecutionRequestIndex}.`,
|
|
44
|
-
);
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const teardownCallRequest = tx.data.getTeardownPublicCallRequest();
|
|
49
|
-
const isInvalidTeardownExecutionRequest =
|
|
50
|
-
(!teardownCallRequest && !tx.publicTeardownFunctionCall.isEmpty()) ||
|
|
51
|
-
(teardownCallRequest && !tx.publicTeardownFunctionCall.isForCallRequest(teardownCallRequest));
|
|
52
|
-
if (isInvalidTeardownExecutionRequest) {
|
|
53
|
-
this.#log.warn(`Rejecting tx ${Tx.getHash(tx)} because of incorrect teardown execution requests.`);
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// TODO: Check logs.
|
|
61
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { type AnyTx, Tx, type TxValidator } from '@aztec/circuit-types';
|
|
2
|
-
import { Fr } from '@aztec/circuits.js';
|
|
3
|
-
import { createDebugLogger } from '@aztec/foundation/log';
|
|
4
|
-
|
|
5
|
-
export interface NullifierSource {
|
|
6
|
-
getNullifierIndex: (nullifier: Fr) => Promise<bigint | undefined>;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export class DoubleSpendTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
10
|
-
#log = createDebugLogger('aztec:sequencer:tx_validator:tx_double_spend');
|
|
11
|
-
#nullifierSource: NullifierSource;
|
|
12
|
-
|
|
13
|
-
constructor(nullifierSource: NullifierSource) {
|
|
14
|
-
this.#nullifierSource = nullifierSource;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async validateTxs(txs: T[]): Promise<[validTxs: T[], invalidTxs: T[]]> {
|
|
18
|
-
const validTxs: T[] = [];
|
|
19
|
-
const invalidTxs: T[] = [];
|
|
20
|
-
const thisBlockNullifiers = new Set<bigint>();
|
|
21
|
-
|
|
22
|
-
for (const tx of txs) {
|
|
23
|
-
if (!(await this.#uniqueNullifiers(tx, thisBlockNullifiers))) {
|
|
24
|
-
invalidTxs.push(tx);
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
validTxs.push(tx);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return [validTxs, invalidTxs];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async #uniqueNullifiers(tx: AnyTx, thisBlockNullifiers: Set<bigint>): Promise<boolean> {
|
|
35
|
-
const nullifiers = tx.data.getNonEmptyNullifiers().map(x => x.toBigInt());
|
|
36
|
-
|
|
37
|
-
// Ditch this tx if it has repeated nullifiers
|
|
38
|
-
const uniqueNullifiers = new Set(nullifiers);
|
|
39
|
-
if (uniqueNullifiers.size !== nullifiers.length) {
|
|
40
|
-
this.#log.warn(`Rejecting tx ${Tx.getHash(tx)} for emitting duplicate nullifiers`);
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
for (const nullifier of nullifiers) {
|
|
45
|
-
if (thisBlockNullifiers.has(nullifier)) {
|
|
46
|
-
this.#log.warn(`Rejecting tx ${Tx.getHash(tx)} for repeating a nullifier in the same block`);
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
thisBlockNullifiers.add(nullifier);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const nullifierIndexes = await Promise.all(nullifiers.map(n => this.#nullifierSource.getNullifierIndex(new Fr(n))));
|
|
54
|
-
|
|
55
|
-
const hasDuplicates = nullifierIndexes.some(index => index !== undefined);
|
|
56
|
-
if (hasDuplicates) {
|
|
57
|
-
this.#log.warn(`Rejecting tx ${Tx.getHash(tx)} for repeating nullifiers present in state trees`);
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { type AnyTx, Tx, type TxValidator } from '@aztec/circuit-types';
|
|
2
|
-
import { type GlobalVariables } from '@aztec/circuits.js';
|
|
3
|
-
import { createDebugLogger } from '@aztec/foundation/log';
|
|
4
|
-
|
|
5
|
-
export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
6
|
-
#log = createDebugLogger('aztec:sequencer:tx_validator:tx_metadata');
|
|
7
|
-
#globalVariables: GlobalVariables;
|
|
8
|
-
|
|
9
|
-
constructor(globalVariables: GlobalVariables) {
|
|
10
|
-
this.#globalVariables = globalVariables;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
validateTxs(txs: T[]): Promise<[validTxs: T[], invalidTxs: T[]]> {
|
|
14
|
-
const validTxs: T[] = [];
|
|
15
|
-
const invalidTxs: T[] = [];
|
|
16
|
-
for (const tx of txs) {
|
|
17
|
-
if (!this.#hasCorrectChainId(tx)) {
|
|
18
|
-
invalidTxs.push(tx);
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (!this.#isValidForBlockNumber(tx)) {
|
|
23
|
-
invalidTxs.push(tx);
|
|
24
|
-
continue;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
validTxs.push(tx);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return Promise.resolve([validTxs, invalidTxs]);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
#hasCorrectChainId(tx: T): boolean {
|
|
34
|
-
if (!tx.data.constants.txContext.chainId.equals(this.#globalVariables.chainId)) {
|
|
35
|
-
this.#log.warn(
|
|
36
|
-
`Rejecting tx ${Tx.getHash(
|
|
37
|
-
tx,
|
|
38
|
-
)} because of incorrect chain ${tx.data.constants.txContext.chainId.toNumber()} != ${this.#globalVariables.chainId.toNumber()}`,
|
|
39
|
-
);
|
|
40
|
-
return false;
|
|
41
|
-
} else {
|
|
42
|
-
return true;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
#isValidForBlockNumber(tx: T): boolean {
|
|
47
|
-
const target =
|
|
48
|
-
tx instanceof Tx
|
|
49
|
-
? tx.data.forRollup?.rollupValidationRequests || tx.data.forPublic!.validationRequests.forRollup
|
|
50
|
-
: tx.data.rollupValidationRequests;
|
|
51
|
-
const maxBlockNumber = target.maxBlockNumber;
|
|
52
|
-
|
|
53
|
-
if (maxBlockNumber.isSome && maxBlockNumber.value < this.#globalVariables.blockNumber) {
|
|
54
|
-
this.#log.warn(`Rejecting tx ${Tx.getHash(tx)} for low max block number`);
|
|
55
|
-
return false;
|
|
56
|
-
} else {
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|