@aztec/sequencer-client 0.42.0 → 0.43.0
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.js +2 -2
- package/dest/config.d.ts +13 -0
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +46 -35
- package/dest/publisher/l1-publisher.d.ts +4 -1
- package/dest/publisher/l1-publisher.d.ts.map +1 -1
- package/dest/publisher/l1-publisher.js +6 -1
- package/dest/publisher/viem-tx-sender.d.ts +3 -0
- package/dest/publisher/viem-tx-sender.d.ts.map +1 -1
- package/dest/publisher/viem-tx-sender.js +15 -1
- package/dest/sequencer/sequencer.d.ts +2 -2
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +22 -14
- package/dest/tx_validator/gas_validator.d.ts +2 -1
- package/dest/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/tx_validator/gas_validator.js +12 -5
- package/dest/tx_validator/phases_validator.d.ts +3 -3
- package/dest/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/tx_validator/phases_validator.js +25 -18
- package/dest/tx_validator/tx_validator_factory.d.ts +4 -3
- package/dest/tx_validator/tx_validator_factory.d.ts.map +1 -1
- package/dest/tx_validator/tx_validator_factory.js +4 -3
- package/package.json +14 -14
- package/src/client/sequencer-client.ts +1 -1
- package/src/config.ts +47 -37
- package/src/publisher/l1-publisher.ts +11 -1
- package/src/publisher/viem-tx-sender.ts +15 -0
- package/src/sequencer/sequencer.ts +25 -16
- package/src/tx_validator/gas_validator.ts +9 -5
- package/src/tx_validator/phases_validator.ts +29 -19
- package/src/tx_validator/tx_validator_factory.ts +8 -4
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
var _GasTxValidator_instances, _GasTxValidator_log, _GasTxValidator_publicDataSource, _GasTxValidator_gasTokenAddress, _GasTxValidator_validateTxFee;
|
|
2
2
|
import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
|
|
3
|
+
import { PublicKernelType } from '@aztec/circuit-types';
|
|
3
4
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
4
5
|
import { GasTokenArtifact } from '@aztec/protocol-contracts/gas-token';
|
|
5
|
-
import { AbstractPhaseManager,
|
|
6
|
+
import { AbstractPhaseManager, computeFeePayerBalanceStorageSlot } from '@aztec/simulator';
|
|
6
7
|
export class GasTxValidator {
|
|
7
|
-
constructor(publicDataSource, gasTokenAddress) {
|
|
8
|
+
constructor(publicDataSource, gasTokenAddress, enforceFees) {
|
|
8
9
|
_GasTxValidator_instances.add(this);
|
|
10
|
+
this.enforceFees = enforceFees;
|
|
9
11
|
_GasTxValidator_log.set(this, createDebugLogger('aztec:sequencer:tx_validator:tx_gas'));
|
|
10
12
|
_GasTxValidator_publicDataSource.set(this, void 0);
|
|
11
13
|
_GasTxValidator_gasTokenAddress.set(this, void 0);
|
|
@@ -30,14 +32,19 @@ _GasTxValidator_log = new WeakMap(), _GasTxValidator_publicDataSource = new Weak
|
|
|
30
32
|
const feePayer = tx.data.feePayer;
|
|
31
33
|
// TODO(@spalladino) Eventually remove the is_zero condition as we should always charge fees to every tx
|
|
32
34
|
if (feePayer.isZero()) {
|
|
33
|
-
|
|
35
|
+
if (this.enforceFees) {
|
|
36
|
+
__classPrivateFieldGet(this, _GasTxValidator_log, "f").warn(`Rejecting transaction ${tx.getTxHash()} due to missing fee payer`);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
34
41
|
}
|
|
35
42
|
// Compute the maximum fee that this tx may pay, based on its gasLimits and maxFeePerGas
|
|
36
43
|
const feeLimit = tx.data.constants.txContext.gasSettings.getFeeLimit();
|
|
37
44
|
// Read current balance of the feePayer
|
|
38
45
|
const initialBalance = await __classPrivateFieldGet(this, _GasTxValidator_publicDataSource, "f").storageRead(__classPrivateFieldGet(this, _GasTxValidator_gasTokenAddress, "f"), computeFeePayerBalanceStorageSlot(feePayer));
|
|
39
46
|
// If there is a claim in this tx that increases the fee payer balance in gas token, add it to balance
|
|
40
|
-
const { [
|
|
47
|
+
const { [PublicKernelType.SETUP]: setupFns } = AbstractPhaseManager.extractEnqueuedPublicCallsByPhase(tx);
|
|
41
48
|
const claimFunctionCall = setupFns.find(fn => fn.contractAddress.equals(__classPrivateFieldGet(this, _GasTxValidator_gasTokenAddress, "f")) &&
|
|
42
49
|
fn.callContext.msgSender.equals(__classPrivateFieldGet(this, _GasTxValidator_gasTokenAddress, "f")) &&
|
|
43
50
|
fn.functionSelector.equals(GasTokenArtifact.functions.find(f => f.name === '_increase_public_balance')) &&
|
|
@@ -51,4 +58,4 @@ _GasTxValidator_log = new WeakMap(), _GasTxValidator_publicDataSource = new Weak
|
|
|
51
58
|
}
|
|
52
59
|
return true;
|
|
53
60
|
};
|
|
54
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
61
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FzX3ZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eF92YWxpZGF0b3IvZ2FzX3ZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE9BQU8sRUFBRSxnQkFBZ0IsRUFBNkIsTUFBTSxzQkFBc0IsQ0FBQztBQUVuRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUN2RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsaUNBQWlDLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQU8zRixNQUFNLE9BQU8sY0FBYztJQUt6QixZQUFZLGdCQUFtQyxFQUFFLGVBQTZCLEVBQVMsV0FBb0I7O1FBQXBCLGdCQUFXLEdBQVgsV0FBVyxDQUFTO1FBSjNHLDhCQUFPLGlCQUFpQixDQUFDLHFDQUFxQyxDQUFDLEVBQUM7UUFDaEUsbURBQXFDO1FBQ3JDLGtEQUErQjtRQUc3Qix1QkFBQSxJQUFJLG9DQUFxQixnQkFBZ0IsTUFBQSxDQUFDO1FBQzFDLHVCQUFBLElBQUksbUNBQW9CLGVBQWUsTUFBQSxDQUFDO0lBQzFDLENBQUM7SUFFRCxLQUFLLENBQUMsV0FBVyxDQUFDLEdBQVM7UUFDekIsTUFBTSxRQUFRLEdBQVMsRUFBRSxDQUFDO1FBQzFCLE1BQU0sVUFBVSxHQUFTLEVBQUUsQ0FBQztRQUU1QixLQUFLLE1BQU0sRUFBRSxJQUFJLEdBQUcsRUFBRSxDQUFDO1lBQ3JCLElBQUksTUFBTSx1QkFBQSxJQUFJLGdFQUFlLE1BQW5CLElBQUksRUFBZ0IsRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFDbEMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNwQixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN0QixDQUFDO1FBQ0gsQ0FB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
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type AllowedElement, Tx, type TxValidator } from '@aztec/circuit-types';
|
|
2
2
|
import { type PublicCallRequest } from '@aztec/circuits.js';
|
|
3
3
|
import { type ContractDataSource } from '@aztec/types/contracts';
|
|
4
4
|
export declare class PhasesTxValidator implements TxValidator<Tx> {
|
|
5
5
|
#private;
|
|
6
6
|
private setupAllowList;
|
|
7
7
|
private contractDataSource;
|
|
8
|
-
constructor(contracts: ContractDataSource, setupAllowList:
|
|
8
|
+
constructor(contracts: ContractDataSource, setupAllowList: AllowedElement[]);
|
|
9
9
|
validateTxs(txs: Tx[]): Promise<[validTxs: Tx[], invalidTxs: Tx[]]>;
|
|
10
|
-
isOnAllowList(publicCall: PublicCallRequest, allowList:
|
|
10
|
+
isOnAllowList(publicCall: PublicCallRequest, allowList: AllowedElement[]): Promise<boolean>;
|
|
11
11
|
}
|
|
12
12
|
//# sourceMappingURL=phases_validator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"phases_validator.d.ts","sourceRoot":"","sources":["../../src/tx_validator/phases_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"phases_validator.d.ts","sourceRoot":"","sources":["../../src/tx_validator/phases_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAoB,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnG,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG5D,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,qBAAa,iBAAkB,YAAW,WAAW,CAAC,EAAE,CAAC;;IAIZ,OAAO,CAAC,cAAc;IAFjE,OAAO,CAAC,kBAAkB,CAA8B;gBAE5C,SAAS,EAAE,kBAAkB,EAAU,cAAc,EAAE,cAAc,EAAE;IAI7E,WAAW,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;IA6CnE,aAAa,CAAC,UAAU,EAAE,iBAAiB,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;CA6ClG"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
var _PhasesTxValidator_instances, _PhasesTxValidator_log, _PhasesTxValidator_validateTx;
|
|
2
2
|
import { __classPrivateFieldGet } from "tslib";
|
|
3
|
-
import { Tx } from '@aztec/circuit-types';
|
|
3
|
+
import { PublicKernelType, Tx } from '@aztec/circuit-types';
|
|
4
4
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
5
|
-
import { AbstractPhaseManager, ContractsDataSourcePublicDB
|
|
5
|
+
import { AbstractPhaseManager, ContractsDataSourcePublicDB } from '@aztec/simulator';
|
|
6
6
|
export class PhasesTxValidator {
|
|
7
7
|
constructor(contracts, setupAllowList) {
|
|
8
8
|
_PhasesTxValidator_instances.add(this);
|
|
@@ -35,23 +35,30 @@ export class PhasesTxValidator {
|
|
|
35
35
|
const { contractAddress, functionSelector } = publicCall;
|
|
36
36
|
// do these checks first since they don't require the contract class
|
|
37
37
|
for (const entry of allowList) {
|
|
38
|
-
if (!('
|
|
39
|
-
|
|
38
|
+
if ('address' in entry && !('selector' in entry)) {
|
|
39
|
+
if (contractAddress.equals(entry.address)) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
40
42
|
}
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
+
if ('address' in entry && 'selector' in entry) {
|
|
44
|
+
if (contractAddress.equals(entry.address) && entry.selector.equals(functionSelector)) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
43
47
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
const contractClass = await this.contractDataSource.getContractInstance(contractAddress);
|
|
49
|
+
if (!contractClass) {
|
|
50
|
+
throw new Error(`Contract not found: ${publicCall.contractAddress.toString()}`);
|
|
51
|
+
}
|
|
52
|
+
if ('classId' in entry && !('selector' in entry)) {
|
|
53
|
+
if (contractClass.contractClassId.equals(entry.classId)) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
52
56
|
}
|
|
53
|
-
if (
|
|
54
|
-
|
|
57
|
+
if ('classId' in entry && 'selector' in entry) {
|
|
58
|
+
if (contractClass.contractClassId.equals(entry.classId) &&
|
|
59
|
+
(entry.selector === undefined || entry.selector.equals(functionSelector))) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
55
62
|
}
|
|
56
63
|
}
|
|
57
64
|
return false;
|
|
@@ -62,7 +69,7 @@ _PhasesTxValidator_log = new WeakMap(), _PhasesTxValidator_instances = new WeakS
|
|
|
62
69
|
__classPrivateFieldGet(this, _PhasesTxValidator_log, "f").debug(`Tx ${Tx.getHash(tx)} does not contain enqueued public functions. Skipping phases validation.`);
|
|
63
70
|
return true;
|
|
64
71
|
}
|
|
65
|
-
const { [
|
|
72
|
+
const { [PublicKernelType.SETUP]: setupFns } = AbstractPhaseManager.extractEnqueuedPublicCallsByPhase(tx);
|
|
66
73
|
for (const setupFn of setupFns) {
|
|
67
74
|
if (!(await this.isOnAllowList(setupFn, this.setupAllowList))) {
|
|
68
75
|
__classPrivateFieldGet(this, _PhasesTxValidator_log, "f").warn(`Rejecting tx ${Tx.getHash(tx)} because it calls setup function not on allow list: ${setupFn.contractAddress}:${setupFn.functionSelector}`);
|
|
@@ -71,4 +78,4 @@ _PhasesTxValidator_log = new WeakMap(), _PhasesTxValidator_instances = new WeakS
|
|
|
71
78
|
}
|
|
72
79
|
return true;
|
|
73
80
|
};
|
|
74
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
81
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGhhc2VzX3ZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eF92YWxpZGF0b3IvcGhhc2VzX3ZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE9BQU8sRUFBdUIsZ0JBQWdCLEVBQUUsRUFBRSxFQUFvQixNQUFNLHNCQUFzQixDQUFDO0FBRW5HLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzFELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSwyQkFBMkIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBR3JGLE1BQU0sT0FBTyxpQkFBaUI7SUFJNUIsWUFBWSxTQUE2QixFQUFVLGNBQWdDOztRQUFoQyxtQkFBYyxHQUFkLGNBQWMsQ0FBa0I7UUFIbkYsaUNBQU8saUJBQWlCLENBQUMsd0NBQXdDLENBQUMsRUFBQztRQUlqRSxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSwyQkFBMkIsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBRUQsS0FBSyxDQUFDLFdBQVcsQ0FBQyxHQUFTO1FBQ3pCLE1BQU0sUUFBUSxHQUFTLEVBQUUsQ0FBQztRQUMxQixNQUFNLFVBQVUsR0FBUyxFQUFFLENBQUM7UUFFNUIsS0FBSyxNQUFNLEVBQUUsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUNyQix3RkFBd0Y7WUFDeEYsbUdBQW1HO1lBQ25HLCtEQUErRDtZQUMvRCxNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLENBQUM7WUFFbEQsSUFBSSxNQUFNLHVCQUFBLElBQUksbUVBQVksTUFBaEIsSUFBSSxFQUFhLEVBQUUsQ0FBQyxFQUFFLENBQUM7Z0JBQy9CLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDcEIsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDdEIs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
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type AllowedElement, type ProcessedTx, type Tx, type TxValidator } from '@aztec/circuit-types';
|
|
2
2
|
import { type GlobalVariables } from '@aztec/circuits.js';
|
|
3
3
|
import { type ContractDataSource } from '@aztec/types/contracts';
|
|
4
4
|
import { type MerkleTreeOperations } from '@aztec/world-state';
|
|
5
5
|
export declare class TxValidatorFactory {
|
|
6
6
|
private merkleTreeDb;
|
|
7
7
|
private contractDataSource;
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
private enforceFees;
|
|
9
|
+
constructor(merkleTreeDb: MerkleTreeOperations, contractDataSource: ContractDataSource, enforceFees: boolean);
|
|
10
|
+
validatorForNewTxs(globalVariables: GlobalVariables, setupAllowList: AllowedElement[]): TxValidator<Tx>;
|
|
10
11
|
validatorForProcessedTxs(): TxValidator<ProcessedTx>;
|
|
11
12
|
}
|
|
12
13
|
//# sourceMappingURL=tx_validator_factory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tx_validator_factory.d.ts","sourceRoot":"","sources":["../../src/tx_validator/tx_validator_factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"tx_validator_factory.d.ts","sourceRoot":"","sources":["../../src/tx_validator/tx_validator_factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAQ/D,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,WAAW;gBAFX,YAAY,EAAE,oBAAoB,EAClC,kBAAkB,EAAE,kBAAkB,EACtC,WAAW,EAAE,OAAO;IAG9B,kBAAkB,CAAC,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC;IASvG,wBAAwB,IAAI,WAAW,CAAC,WAAW,CAAC;CAGrD"}
|
|
@@ -6,15 +6,16 @@ import { GasTxValidator } from './gas_validator.js';
|
|
|
6
6
|
import { MetadataTxValidator } from './metadata_validator.js';
|
|
7
7
|
import { PhasesTxValidator } from './phases_validator.js';
|
|
8
8
|
export class TxValidatorFactory {
|
|
9
|
-
constructor(merkleTreeDb, contractDataSource) {
|
|
9
|
+
constructor(merkleTreeDb, contractDataSource, enforceFees) {
|
|
10
10
|
this.merkleTreeDb = merkleTreeDb;
|
|
11
11
|
this.contractDataSource = contractDataSource;
|
|
12
|
+
this.enforceFees = enforceFees;
|
|
12
13
|
}
|
|
13
14
|
validatorForNewTxs(globalVariables, setupAllowList) {
|
|
14
|
-
return new AggregateTxValidator(new MetadataTxValidator(globalVariables), new DoubleSpendTxValidator(new WorldStateDB(this.merkleTreeDb)), new PhasesTxValidator(this.contractDataSource, setupAllowList), new GasTxValidator(new WorldStatePublicDB(this.merkleTreeDb), GasTokenAddress));
|
|
15
|
+
return new AggregateTxValidator(new MetadataTxValidator(globalVariables), new DoubleSpendTxValidator(new WorldStateDB(this.merkleTreeDb)), new PhasesTxValidator(this.contractDataSource, setupAllowList), new GasTxValidator(new WorldStatePublicDB(this.merkleTreeDb), GasTokenAddress, this.enforceFees));
|
|
15
16
|
}
|
|
16
17
|
validatorForProcessedTxs() {
|
|
17
18
|
return new DoubleSpendTxValidator(new WorldStateDB(this.merkleTreeDb));
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhfdmFsaWRhdG9yX2ZhY3RvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHhfdmFsaWRhdG9yL3R4X3ZhbGlkYXRvcl9mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUN0RSxPQUFPLEVBQUUsWUFBWSxFQUFFLGtCQUFrQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFJcEUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDbkUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzlELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRTFELE1BQU0sT0FBTyxrQkFBa0I7SUFDN0IsWUFDVSxZQUFrQyxFQUNsQyxrQkFBc0MsRUFDdEMsV0FBb0I7UUFGcEIsaUJBQVksR0FBWixZQUFZLENBQXNCO1FBQ2xDLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDdEMsZ0JBQVcsR0FBWCxXQUFXLENBQVM7SUFDM0IsQ0FBQztJQUVKLGtCQUFrQixDQUFDLGVBQWdDLEVBQUUsY0FBZ0M7UUFDbkYsT0FBTyxJQUFJLG9CQUFvQixDQUM3QixJQUFJLG1CQUFtQixDQUFDLGVBQWUsQ0FBQyxFQUN4QyxJQUFJLHNCQUFzQixDQUFDLElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxFQUMvRCxJQUFJLGlCQUFpQixDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxjQUFjLENBQUMsRUFDOUQsSUFBSSxjQUFjLENBQUMsSUFBSSxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsZUFBZSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FDakcsQ0FBQztJQUNKLENBQUM7SUFFRCx3QkFBd0I7UUFDdEIsT0FBTyxJQUFJLHNCQUFzQixDQUFDLElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7Q0FDRiJ9
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/sequencer-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.43.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dest/index.js",
|
|
6
6
|
"typedocOptions": {
|
|
@@ -24,19 +24,19 @@
|
|
|
24
24
|
"test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --config jest.integration.config.json"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@aztec/circuit-types": "0.
|
|
28
|
-
"@aztec/circuits.js": "0.
|
|
29
|
-
"@aztec/ethereum": "0.
|
|
30
|
-
"@aztec/foundation": "0.
|
|
31
|
-
"@aztec/l1-artifacts": "0.
|
|
32
|
-
"@aztec/merkle-tree": "0.
|
|
33
|
-
"@aztec/noir-contracts.js": "0.
|
|
34
|
-
"@aztec/noir-protocol-circuits-types": "0.
|
|
35
|
-
"@aztec/p2p": "0.
|
|
36
|
-
"@aztec/protocol-contracts": "0.
|
|
37
|
-
"@aztec/simulator": "0.
|
|
38
|
-
"@aztec/types": "0.
|
|
39
|
-
"@aztec/world-state": "0.
|
|
27
|
+
"@aztec/circuit-types": "0.43.0",
|
|
28
|
+
"@aztec/circuits.js": "0.43.0",
|
|
29
|
+
"@aztec/ethereum": "0.43.0",
|
|
30
|
+
"@aztec/foundation": "0.43.0",
|
|
31
|
+
"@aztec/l1-artifacts": "0.43.0",
|
|
32
|
+
"@aztec/merkle-tree": "0.43.0",
|
|
33
|
+
"@aztec/noir-contracts.js": "0.43.0",
|
|
34
|
+
"@aztec/noir-protocol-circuits-types": "0.43.0",
|
|
35
|
+
"@aztec/p2p": "0.43.0",
|
|
36
|
+
"@aztec/protocol-contracts": "0.43.0",
|
|
37
|
+
"@aztec/simulator": "0.43.0",
|
|
38
|
+
"@aztec/types": "0.43.0",
|
|
39
|
+
"@aztec/world-state": "0.43.0",
|
|
40
40
|
"@noir-lang/acvm_js": "portal:../../noir/packages/acvm_js",
|
|
41
41
|
"@noir-lang/types": "portal:../../noir/packages/types",
|
|
42
42
|
"lodash.chunk": "^4.2.0",
|
|
@@ -54,7 +54,7 @@ export class SequencerClient {
|
|
|
54
54
|
l2BlockSource,
|
|
55
55
|
l1ToL2MessageSource,
|
|
56
56
|
publicProcessorFactory,
|
|
57
|
-
new TxValidatorFactory(merkleTreeDb, contractDataSource),
|
|
57
|
+
new TxValidatorFactory(merkleTreeDb, contractDataSource, !!config.enforceFees),
|
|
58
58
|
config,
|
|
59
59
|
);
|
|
60
60
|
|
package/src/config.ts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type AllowedElement } from '@aztec/circuit-types';
|
|
2
2
|
import { AztecAddress, Fr, FunctionSelector, getContractClassFromArtifact } from '@aztec/circuits.js';
|
|
3
3
|
import { type L1ContractAddresses, NULL_KEY } from '@aztec/ethereum';
|
|
4
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
|
-
import { EcdsaAccountContractArtifact } from '@aztec/noir-contracts.js/EcdsaAccount';
|
|
6
5
|
import { FPCContract } from '@aztec/noir-contracts.js/FPC';
|
|
7
|
-
import { SchnorrAccountContractArtifact } from '@aztec/noir-contracts.js/SchnorrAccount';
|
|
8
|
-
import { SchnorrHardcodedAccountContractArtifact } from '@aztec/noir-contracts.js/SchnorrHardcodedAccount';
|
|
9
|
-
import { SchnorrSingleKeyAccountContractArtifact } from '@aztec/noir-contracts.js/SchnorrSingleKeyAccount';
|
|
10
6
|
import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
|
|
7
|
+
import { AuthRegistryAddress } from '@aztec/protocol-contracts/auth-registry';
|
|
11
8
|
import { GasTokenAddress } from '@aztec/protocol-contracts/gas-token';
|
|
12
9
|
|
|
13
10
|
import { type Hex } from 'viem';
|
|
@@ -62,6 +59,7 @@ export function getConfigEnvVars(): SequencerClientConfig {
|
|
|
62
59
|
FEE_RECIPIENT,
|
|
63
60
|
ACVM_WORKING_DIRECTORY,
|
|
64
61
|
ACVM_BINARY_PATH,
|
|
62
|
+
ENFORCE_FEES = '',
|
|
65
63
|
} = process.env;
|
|
66
64
|
|
|
67
65
|
const publisherPrivateKey: Hex = SEQ_PUBLISHER_PRIVATE_KEY
|
|
@@ -83,6 +81,7 @@ export function getConfigEnvVars(): SequencerClientConfig {
|
|
|
83
81
|
};
|
|
84
82
|
|
|
85
83
|
return {
|
|
84
|
+
enforceFees: ['1', 'true'].includes(ENFORCE_FEES),
|
|
86
85
|
rpcUrl: ETHEREUM_HOST ? ETHEREUM_HOST : '',
|
|
87
86
|
chainId: CHAIN_ID ? +CHAIN_ID : 31337, // 31337 is the default chain id for anvil
|
|
88
87
|
version: VERSION ? +VERSION : 1, // 1 is our default version
|
|
@@ -100,59 +99,70 @@ export function getConfigEnvVars(): SequencerClientConfig {
|
|
|
100
99
|
feeRecipient: FEE_RECIPIENT ? AztecAddress.fromString(FEE_RECIPIENT) : undefined,
|
|
101
100
|
acvmWorkingDirectory: ACVM_WORKING_DIRECTORY ? ACVM_WORKING_DIRECTORY : undefined,
|
|
102
101
|
acvmBinaryPath: ACVM_BINARY_PATH ? ACVM_BINARY_PATH : undefined,
|
|
103
|
-
|
|
102
|
+
allowedInSetup: SEQ_ALLOWED_SETUP_FN
|
|
104
103
|
? parseSequencerAllowList(SEQ_ALLOWED_SETUP_FN)
|
|
105
104
|
: getDefaultAllowedSetupFunctions(),
|
|
106
|
-
|
|
105
|
+
allowedInTeardown: SEQ_ALLOWED_TEARDOWN_FN
|
|
107
106
|
? parseSequencerAllowList(SEQ_ALLOWED_TEARDOWN_FN)
|
|
108
107
|
: getDefaultAllowedTeardownFunctions(),
|
|
109
108
|
};
|
|
110
109
|
}
|
|
111
110
|
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
/**
|
|
112
|
+
* Parses a string to a list of allowed elements.
|
|
113
|
+
* Each encoded is expected to be of one of the following formats
|
|
114
|
+
* `I:${address}`
|
|
115
|
+
* `I:${address}:${selector}`
|
|
116
|
+
* `C:${classId}`
|
|
117
|
+
* `C:${classId}:${selector}`
|
|
118
|
+
*
|
|
119
|
+
* @param value The string to parse
|
|
120
|
+
* @returns A list of allowed elements
|
|
121
|
+
*/
|
|
122
|
+
export function parseSequencerAllowList(value: string): AllowedElement[] {
|
|
123
|
+
const entries: AllowedElement[] = [];
|
|
114
124
|
|
|
115
125
|
if (!value) {
|
|
116
126
|
return entries;
|
|
117
127
|
}
|
|
118
128
|
|
|
119
129
|
for (const val of value.split(',')) {
|
|
120
|
-
const [identifierString, selectorString] = val.split(':');
|
|
121
|
-
const selector = FunctionSelector.fromString(selectorString);
|
|
130
|
+
const [typeString, identifierString, selectorString] = val.split(':');
|
|
131
|
+
const selector = selectorString !== undefined ? FunctionSelector.fromString(selectorString) : undefined;
|
|
122
132
|
|
|
123
|
-
if (
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
+
if (typeString === 'I') {
|
|
134
|
+
if (selector) {
|
|
135
|
+
entries.push({
|
|
136
|
+
address: AztecAddress.fromString(identifierString),
|
|
137
|
+
selector,
|
|
138
|
+
});
|
|
139
|
+
} else {
|
|
140
|
+
entries.push({
|
|
141
|
+
address: AztecAddress.fromString(identifierString),
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
} else if (typeString === 'C') {
|
|
145
|
+
if (selector) {
|
|
146
|
+
entries.push({
|
|
147
|
+
classId: Fr.fromString(identifierString),
|
|
148
|
+
selector,
|
|
149
|
+
});
|
|
150
|
+
} else {
|
|
151
|
+
entries.push({
|
|
152
|
+
classId: Fr.fromString(identifierString),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
133
155
|
}
|
|
134
156
|
}
|
|
135
157
|
|
|
136
158
|
return entries;
|
|
137
159
|
}
|
|
138
160
|
|
|
139
|
-
function getDefaultAllowedSetupFunctions():
|
|
161
|
+
function getDefaultAllowedSetupFunctions(): AllowedElement[] {
|
|
140
162
|
return [
|
|
163
|
+
// needed for authwit support
|
|
141
164
|
{
|
|
142
|
-
|
|
143
|
-
selector: FunctionSelector.fromSignature('approve_public_authwit(Field)'),
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
classId: getContractClassFromArtifact(SchnorrHardcodedAccountContractArtifact).id,
|
|
147
|
-
selector: FunctionSelector.fromSignature('approve_public_authwit(Field)'),
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
classId: getContractClassFromArtifact(SchnorrSingleKeyAccountContractArtifact).id,
|
|
151
|
-
selector: FunctionSelector.fromSignature('approve_public_authwit(Field)'),
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
classId: getContractClassFromArtifact(EcdsaAccountContractArtifact).id,
|
|
155
|
-
selector: FunctionSelector.fromSignature('approve_public_authwit(Field)'),
|
|
165
|
+
address: AuthRegistryAddress,
|
|
156
166
|
},
|
|
157
167
|
// needed for claiming on the same tx as a spend
|
|
158
168
|
{
|
|
@@ -171,7 +181,7 @@ function getDefaultAllowedSetupFunctions(): AllowedFunction[] {
|
|
|
171
181
|
];
|
|
172
182
|
}
|
|
173
183
|
|
|
174
|
-
function getDefaultAllowedTeardownFunctions():
|
|
184
|
+
function getDefaultAllowedTeardownFunctions(): AllowedElement[] {
|
|
175
185
|
return [
|
|
176
186
|
{
|
|
177
187
|
classId: getContractClassFromArtifact(FPCContract.artifact).id,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type L2Block } from '@aztec/circuit-types';
|
|
2
2
|
import { type L1PublishStats } from '@aztec/circuit-types/stats';
|
|
3
|
-
import { type Fr, type Proof } from '@aztec/circuits.js';
|
|
3
|
+
import { type EthAddress, type Fr, type Proof } from '@aztec/circuits.js';
|
|
4
4
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
5
5
|
import { serializeToBuffer } from '@aztec/foundation/serialize';
|
|
6
6
|
import { InterruptibleSleep } from '@aztec/foundation/sleep';
|
|
@@ -42,6 +42,10 @@ export type MinimalTransactionReceipt = {
|
|
|
42
42
|
* Pushes txs to the L1 chain and waits for their completion.
|
|
43
43
|
*/
|
|
44
44
|
export interface L1PublisherTxSender {
|
|
45
|
+
getSenderAddress(): Promise<EthAddress>;
|
|
46
|
+
|
|
47
|
+
getSubmitterAddressForBlock(blockNumber: number): Promise<EthAddress>;
|
|
48
|
+
|
|
45
49
|
/**
|
|
46
50
|
* Publishes tx effects to Availability Oracle.
|
|
47
51
|
* @param encodedBody - Encoded block body.
|
|
@@ -117,6 +121,12 @@ export class L1Publisher implements L2BlockReceiver {
|
|
|
117
121
|
this.sleepTimeMs = config?.l1BlockPublishRetryIntervalMS ?? 60_000;
|
|
118
122
|
}
|
|
119
123
|
|
|
124
|
+
public async isItMyTurnToSubmit(blockNumber: number): Promise<boolean> {
|
|
125
|
+
const submitter = await this.txSender.getSubmitterAddressForBlock(blockNumber);
|
|
126
|
+
const sender = await this.txSender.getSenderAddress();
|
|
127
|
+
return submitter.isZero() || submitter.equals(sender);
|
|
128
|
+
}
|
|
129
|
+
|
|
120
130
|
/**
|
|
121
131
|
* Publishes L2 block on L1.
|
|
122
132
|
* @param block - L2 block to publish.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type L2Block } from '@aztec/circuit-types';
|
|
2
|
+
import { EthAddress } from '@aztec/circuits.js';
|
|
2
3
|
import { createEthereumChain } from '@aztec/ethereum';
|
|
3
4
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
4
5
|
import { AvailabilityOracleAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
@@ -71,6 +72,20 @@ export class ViemTxSender implements L1PublisherTxSender {
|
|
|
71
72
|
});
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
getSenderAddress(): Promise<EthAddress> {
|
|
76
|
+
return Promise.resolve(EthAddress.fromString(this.account.address));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async getSubmitterAddressForBlock(blockNumber: number): Promise<EthAddress> {
|
|
80
|
+
try {
|
|
81
|
+
const submitter = await this.rollupContract.read.whoseTurnIsIt([BigInt(blockNumber)]);
|
|
82
|
+
return EthAddress.fromString(submitter);
|
|
83
|
+
} catch (err) {
|
|
84
|
+
this.log.warn(`Failed to get submitter for block ${blockNumber}: ${err}`);
|
|
85
|
+
return EthAddress.ZERO;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
74
89
|
async getCurrentArchive(): Promise<Buffer> {
|
|
75
90
|
const archive = await this.rollupContract.read.archive();
|
|
76
91
|
return Buffer.from(archive.replace('0x', ''), 'hex');
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
type TxValidator,
|
|
8
8
|
} from '@aztec/circuit-types';
|
|
9
9
|
import {
|
|
10
|
-
type
|
|
10
|
+
type AllowedElement,
|
|
11
11
|
BlockProofError,
|
|
12
12
|
type BlockProver,
|
|
13
13
|
PROVING_STATUS,
|
|
@@ -46,8 +46,8 @@ export class Sequencer {
|
|
|
46
46
|
private _feeRecipient = AztecAddress.ZERO;
|
|
47
47
|
private lastPublishedBlock = 0;
|
|
48
48
|
private state = SequencerState.STOPPED;
|
|
49
|
-
private
|
|
50
|
-
private
|
|
49
|
+
private allowedInSetup: AllowedElement[] = [];
|
|
50
|
+
private allowedInTeardown: AllowedElement[] = [];
|
|
51
51
|
private maxBlockSizeInBytes: number = 1024 * 1024;
|
|
52
52
|
|
|
53
53
|
constructor(
|
|
@@ -87,15 +87,15 @@ export class Sequencer {
|
|
|
87
87
|
if (config.feeRecipient) {
|
|
88
88
|
this._feeRecipient = config.feeRecipient;
|
|
89
89
|
}
|
|
90
|
-
if (config.
|
|
91
|
-
this.
|
|
90
|
+
if (config.allowedInSetup) {
|
|
91
|
+
this.allowedInSetup = config.allowedInSetup;
|
|
92
92
|
}
|
|
93
93
|
if (config.maxBlockSizeInBytes) {
|
|
94
94
|
this.maxBlockSizeInBytes = config.maxBlockSizeInBytes;
|
|
95
95
|
}
|
|
96
96
|
// TODO(#5917) remove this. it is no longer needed since we don't need to whitelist functions in teardown
|
|
97
|
-
if (config.
|
|
98
|
-
this.
|
|
97
|
+
if (config.allowedInTeardown) {
|
|
98
|
+
this.allowedInTeardown = config.allowedInTeardown;
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
@@ -162,6 +162,18 @@ export class Sequencer {
|
|
|
162
162
|
return;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
const historicalHeader = (await this.l2BlockSource.getBlock(-1))?.header;
|
|
166
|
+
const newBlockNumber =
|
|
167
|
+
(historicalHeader === undefined
|
|
168
|
+
? await this.l2BlockSource.getBlockNumber()
|
|
169
|
+
: Number(historicalHeader.globalVariables.blockNumber.toBigInt())) + 1;
|
|
170
|
+
|
|
171
|
+
// Do not go forward with new block if not my turn
|
|
172
|
+
if (!(await this.publisher.isItMyTurnToSubmit(newBlockNumber))) {
|
|
173
|
+
this.log.verbose('Not my turn to submit block');
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
165
177
|
const workTimer = new Timer();
|
|
166
178
|
this.state = SequencerState.WAITING_FOR_TXS;
|
|
167
179
|
|
|
@@ -172,12 +184,6 @@ export class Sequencer {
|
|
|
172
184
|
}
|
|
173
185
|
this.log.debug(`Retrieved ${pendingTxs.length} txs from P2P pool`);
|
|
174
186
|
|
|
175
|
-
const historicalHeader = (await this.l2BlockSource.getBlock(-1))?.header;
|
|
176
|
-
const newBlockNumber =
|
|
177
|
-
(historicalHeader === undefined
|
|
178
|
-
? await this.l2BlockSource.getBlockNumber()
|
|
179
|
-
: Number(historicalHeader.globalVariables.blockNumber.toBigInt())) + 1;
|
|
180
|
-
|
|
181
187
|
/**
|
|
182
188
|
* We'll call this function before running expensive operations to avoid wasted work.
|
|
183
189
|
*/
|
|
@@ -186,6 +192,9 @@ export class Sequencer {
|
|
|
186
192
|
if (currentBlockNumber + 1 !== newBlockNumber) {
|
|
187
193
|
throw new Error('New block was emitted while building block');
|
|
188
194
|
}
|
|
195
|
+
if (!(await this.publisher.isItMyTurnToSubmit(newBlockNumber))) {
|
|
196
|
+
throw new Error(`Not this sequencer turn to submit block`);
|
|
197
|
+
}
|
|
189
198
|
};
|
|
190
199
|
|
|
191
200
|
const newGlobalVariables = await this.globalsBuilder.buildGlobalVariables(
|
|
@@ -197,7 +206,7 @@ export class Sequencer {
|
|
|
197
206
|
// TODO: It should be responsibility of the P2P layer to validate txs before passing them on here
|
|
198
207
|
const allValidTxs = await this.takeValidTxs(
|
|
199
208
|
pendingTxs,
|
|
200
|
-
this.txValidatorFactory.validatorForNewTxs(newGlobalVariables, this.
|
|
209
|
+
this.txValidatorFactory.validatorForNewTxs(newGlobalVariables, this.allowedInSetup),
|
|
201
210
|
);
|
|
202
211
|
|
|
203
212
|
// TODO: We are taking the size of the tx from private-land, but we should be doing this after running
|
|
@@ -321,10 +330,10 @@ export class Sequencer {
|
|
|
321
330
|
|
|
322
331
|
const toReturn: Tx[] = [];
|
|
323
332
|
for (const tx of txs) {
|
|
324
|
-
const txSize = tx.
|
|
333
|
+
const txSize = tx.getSize() - tx.proof.toBuffer().length;
|
|
325
334
|
if (totalSize + txSize > maxSize) {
|
|
326
335
|
this.log.warn(
|
|
327
|
-
`Dropping tx ${tx.getTxHash()} with size ${txSize} due to exceeding ${maxSize} block size limit (currently at ${totalSize})`,
|
|
336
|
+
`Dropping tx ${tx.getTxHash()} with estimated size ${txSize} due to exceeding ${maxSize} block size limit (currently at ${totalSize})`,
|
|
328
337
|
);
|
|
329
338
|
continue;
|
|
330
339
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { type Tx, type TxValidator } from '@aztec/circuit-types';
|
|
1
|
+
import { PublicKernelType, type Tx, type TxValidator } from '@aztec/circuit-types';
|
|
2
2
|
import { type AztecAddress, type Fr } from '@aztec/circuits.js';
|
|
3
3
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { GasTokenArtifact } from '@aztec/protocol-contracts/gas-token';
|
|
5
|
-
import { AbstractPhaseManager,
|
|
5
|
+
import { AbstractPhaseManager, computeFeePayerBalanceStorageSlot } from '@aztec/simulator';
|
|
6
6
|
|
|
7
7
|
/** Provides a view into public contract state */
|
|
8
8
|
export interface PublicStateSource {
|
|
@@ -14,7 +14,7 @@ export class GasTxValidator implements TxValidator<Tx> {
|
|
|
14
14
|
#publicDataSource: PublicStateSource;
|
|
15
15
|
#gasTokenAddress: AztecAddress;
|
|
16
16
|
|
|
17
|
-
constructor(publicDataSource: PublicStateSource, gasTokenAddress: AztecAddress) {
|
|
17
|
+
constructor(publicDataSource: PublicStateSource, gasTokenAddress: AztecAddress, public enforceFees: boolean) {
|
|
18
18
|
this.#publicDataSource = publicDataSource;
|
|
19
19
|
this.#gasTokenAddress = gasTokenAddress;
|
|
20
20
|
}
|
|
@@ -38,7 +38,11 @@ export class GasTxValidator implements TxValidator<Tx> {
|
|
|
38
38
|
const feePayer = tx.data.feePayer;
|
|
39
39
|
// TODO(@spalladino) Eventually remove the is_zero condition as we should always charge fees to every tx
|
|
40
40
|
if (feePayer.isZero()) {
|
|
41
|
-
|
|
41
|
+
if (this.enforceFees) {
|
|
42
|
+
this.#log.warn(`Rejecting transaction ${tx.getTxHash()} due to missing fee payer`);
|
|
43
|
+
} else {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
// Compute the maximum fee that this tx may pay, based on its gasLimits and maxFeePerGas
|
|
@@ -51,7 +55,7 @@ export class GasTxValidator implements TxValidator<Tx> {
|
|
|
51
55
|
);
|
|
52
56
|
|
|
53
57
|
// If there is a claim in this tx that increases the fee payer balance in gas token, add it to balance
|
|
54
|
-
const { [
|
|
58
|
+
const { [PublicKernelType.SETUP]: setupFns } = AbstractPhaseManager.extractEnqueuedPublicCallsByPhase(tx);
|
|
55
59
|
const claimFunctionCall = setupFns.find(
|
|
56
60
|
fn =>
|
|
57
61
|
fn.contractAddress.equals(this.#gasTokenAddress) &&
|