@aztec/sequencer-client 0.83.1 → 0.84.0-alpha-testnet.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/config.d.ts +3 -14
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +5 -53
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -1
- package/dest/sequencer/index.d.ts +0 -1
- package/dest/sequencer/index.d.ts.map +1 -1
- package/dest/sequencer/index.js +0 -1
- package/dest/sequencer/sequencer.d.ts +1 -1
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +8 -8
- package/dest/tx_validator/tx_validator_factory.d.ts.map +1 -1
- package/dest/tx_validator/tx_validator_factory.js +2 -20
- package/package.json +25 -25
- package/src/config.ts +4 -60
- package/src/index.ts +1 -1
- package/src/sequencer/index.ts +0 -1
- package/src/sequencer/sequencer.ts +10 -7
- package/src/tx_validator/tx_validator_factory.ts +3 -26
- package/dest/sequencer/allowed.d.ts +0 -3
- package/dest/sequencer/allowed.d.ts.map +0 -1
- package/dest/sequencer/allowed.js +0 -27
- package/dest/tx_validator/gas_validator.d.ts +0 -14
- package/dest/tx_validator/gas_validator.d.ts.map +0 -1
- package/dest/tx_validator/gas_validator.js +0 -76
- package/dest/tx_validator/phases_validator.d.ts +0 -13
- package/dest/tx_validator/phases_validator.d.ts.map +0 -1
- package/dest/tx_validator/phases_validator.js +0 -83
- package/dest/tx_validator/test_utils.d.ts +0 -17
- package/dest/tx_validator/test_utils.d.ts.map +0 -1
- package/dest/tx_validator/test_utils.js +0 -22
- package/src/sequencer/allowed.ts +0 -36
- package/src/tx_validator/gas_validator.ts +0 -100
- package/src/tx_validator/phases_validator.ts +0 -104
- package/src/tx_validator/test_utils.ts +0 -43
package/dest/config.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type L1ContractsConfig, type L1ReaderConfig } from '@aztec/ethereum';
|
|
2
2
|
import { type ConfigMappingsType } from '@aztec/foundation/config';
|
|
3
|
-
import { type
|
|
3
|
+
import { type P2PConfig } from '@aztec/p2p';
|
|
4
|
+
import { type ChainConfig, type SequencerConfig } from '@aztec/stdlib/config';
|
|
4
5
|
import { type ValidatorClientConfig } from '@aztec/validator-client';
|
|
5
6
|
import { type PublisherConfig, type TxSenderConfig } from './publisher/config.js';
|
|
6
7
|
export * from './publisher/config.js';
|
|
@@ -8,23 +9,11 @@ export type { SequencerConfig };
|
|
|
8
9
|
/**
|
|
9
10
|
* Configuration settings for the SequencerClient.
|
|
10
11
|
*/
|
|
11
|
-
export type SequencerClientConfig = PublisherConfig & ValidatorClientConfig & TxSenderConfig & SequencerConfig & L1ReaderConfig & ChainConfig & Pick<L1ContractsConfig, 'ethereumSlotDuration' | 'aztecSlotDuration' | 'aztecEpochDuration'>;
|
|
12
|
+
export type SequencerClientConfig = PublisherConfig & ValidatorClientConfig & TxSenderConfig & SequencerConfig & L1ReaderConfig & ChainConfig & Pick<P2PConfig, 'txPublicSetupAllowList'> & Pick<L1ContractsConfig, 'ethereumSlotDuration' | 'aztecSlotDuration' | 'aztecEpochDuration'>;
|
|
12
13
|
export declare const sequencerConfigMappings: ConfigMappingsType<SequencerConfig>;
|
|
13
14
|
export declare const sequencerClientConfigMappings: ConfigMappingsType<SequencerClientConfig>;
|
|
14
15
|
/**
|
|
15
16
|
* Creates an instance of SequencerClientConfig out of environment variables using sensible defaults for integration testing if not set.
|
|
16
17
|
*/
|
|
17
18
|
export declare function getConfigEnvVars(): SequencerClientConfig;
|
|
18
|
-
/**
|
|
19
|
-
* Parses a string to a list of allowed elements.
|
|
20
|
-
* Each encoded is expected to be of one of the following formats
|
|
21
|
-
* `I:${address}`
|
|
22
|
-
* `I:${address}:${selector}`
|
|
23
|
-
* `C:${classId}`
|
|
24
|
-
* `C:${classId}:${selector}`
|
|
25
|
-
*
|
|
26
|
-
* @param value The string to parse
|
|
27
|
-
* @returns A list of allowed elements
|
|
28
|
-
*/
|
|
29
|
-
export declare function parseSequencerAllowList(value: string): AllowedElement[];
|
|
30
19
|
//# sourceMappingURL=config.d.ts.map
|
package/dest/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAGpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAGpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,YAAY,CAAC;AAE/D,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAuB,MAAM,sBAAsB,CAAC;AACnG,OAAO,EAAE,KAAK,qBAAqB,EAAiC,MAAM,yBAAyB,CAAC;AAEpG,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EAGpB,MAAM,uBAAuB,CAAC;AAE/B,cAAc,uBAAuB,CAAC;AACtC,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,eAAe,GACjD,qBAAqB,GACrB,cAAc,GACd,eAAe,GACf,cAAc,GACd,WAAW,GACX,IAAI,CAAC,SAAS,EAAE,wBAAwB,CAAC,GACzC,IAAI,CAAC,iBAAiB,EAAE,sBAAsB,GAAG,mBAAmB,GAAG,oBAAoB,CAAC,CAAC;AAE/F,eAAO,MAAM,uBAAuB,EAAE,kBAAkB,CAAC,eAAe,CAmEvE,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,kBAAkB,CAAC,qBAAqB,CAQnF,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,qBAAqB,CAExD"}
|
package/dest/config.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { l1ContractsConfigMappings, l1ReaderConfigMappings } from '@aztec/ethereum';
|
|
2
2
|
import { booleanConfigHelper, getConfigFromMappings, numberConfigHelper, pickConfigMappings } from '@aztec/foundation/config';
|
|
3
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
|
-
import {
|
|
5
|
-
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
4
|
+
import { p2pConfigMappings } from '@aztec/p2p';
|
|
6
5
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
7
6
|
import { chainConfigMappings } from '@aztec/stdlib/config';
|
|
8
7
|
import { validatorClientConfigMappings } from '@aztec/validator-client';
|
|
@@ -52,12 +51,6 @@ export const sequencerConfigMappings = {
|
|
|
52
51
|
env: 'ACVM_BINARY_PATH',
|
|
53
52
|
description: 'The path to the ACVM binary'
|
|
54
53
|
},
|
|
55
|
-
allowedInSetup: {
|
|
56
|
-
env: 'SEQ_ALLOWED_SETUP_FN',
|
|
57
|
-
parseEnv: (val)=>parseSequencerAllowList(val),
|
|
58
|
-
description: 'The list of functions calls allowed to run in setup',
|
|
59
|
-
printDefault: ()=>'AuthRegistry, FeeJuice.increase_public_balance, Token.increase_public_balance, FPC.prepare_fee'
|
|
60
|
-
},
|
|
61
54
|
maxBlockSizeInBytes: {
|
|
62
55
|
env: 'SEQ_MAX_BLOCK_SIZE_IN_BYTES',
|
|
63
56
|
description: 'Max block size',
|
|
@@ -79,7 +72,10 @@ export const sequencerConfigMappings = {
|
|
|
79
72
|
env: 'SEQ_MAX_L1_TX_INCLUSION_TIME_INTO_SLOT',
|
|
80
73
|
description: 'How many seconds into an L1 slot we can still send a tx and get it mined.',
|
|
81
74
|
parseEnv: (val)=>val ? parseInt(val, 10) : undefined
|
|
82
|
-
}
|
|
75
|
+
},
|
|
76
|
+
...pickConfigMappings(p2pConfigMappings, [
|
|
77
|
+
'txPublicSetupAllowList'
|
|
78
|
+
])
|
|
83
79
|
};
|
|
84
80
|
export const sequencerClientConfigMappings = {
|
|
85
81
|
...validatorClientConfigMappings,
|
|
@@ -99,47 +95,3 @@ export const sequencerClientConfigMappings = {
|
|
|
99
95
|
*/ export function getConfigEnvVars() {
|
|
100
96
|
return getConfigFromMappings(sequencerClientConfigMappings);
|
|
101
97
|
}
|
|
102
|
-
/**
|
|
103
|
-
* Parses a string to a list of allowed elements.
|
|
104
|
-
* Each encoded is expected to be of one of the following formats
|
|
105
|
-
* `I:${address}`
|
|
106
|
-
* `I:${address}:${selector}`
|
|
107
|
-
* `C:${classId}`
|
|
108
|
-
* `C:${classId}:${selector}`
|
|
109
|
-
*
|
|
110
|
-
* @param value The string to parse
|
|
111
|
-
* @returns A list of allowed elements
|
|
112
|
-
*/ export function parseSequencerAllowList(value) {
|
|
113
|
-
const entries = [];
|
|
114
|
-
if (!value) {
|
|
115
|
-
return entries;
|
|
116
|
-
}
|
|
117
|
-
for (const val of value.split(',')){
|
|
118
|
-
const [typeString, identifierString, selectorString] = val.split(':');
|
|
119
|
-
const selector = selectorString !== undefined ? FunctionSelector.fromString(selectorString) : undefined;
|
|
120
|
-
if (typeString === 'I') {
|
|
121
|
-
if (selector) {
|
|
122
|
-
entries.push({
|
|
123
|
-
address: AztecAddress.fromString(identifierString),
|
|
124
|
-
selector
|
|
125
|
-
});
|
|
126
|
-
} else {
|
|
127
|
-
entries.push({
|
|
128
|
-
address: AztecAddress.fromString(identifierString)
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
} else if (typeString === 'C') {
|
|
132
|
-
if (selector) {
|
|
133
|
-
entries.push({
|
|
134
|
-
classId: Fr.fromHexString(identifierString),
|
|
135
|
-
selector
|
|
136
|
-
});
|
|
137
|
-
} else {
|
|
138
|
-
entries.push({
|
|
139
|
-
classId: Fr.fromHexString(identifierString)
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
return entries;
|
|
145
|
-
}
|
package/dest/index.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ export * from './config.js';
|
|
|
3
3
|
export * from './publisher/index.js';
|
|
4
4
|
export * from './tx_validator/tx_validator_factory.js';
|
|
5
5
|
export * from './slasher/index.js';
|
|
6
|
-
export { Sequencer, SequencerState
|
|
6
|
+
export { Sequencer, SequencerState } from './sequencer/index.js';
|
|
7
7
|
export * from './global_variable_builder/index.js';
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dest/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wCAAwC,CAAC;AACvD,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wCAAwC,CAAC;AACvD,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAIjE,cAAc,oCAAoC,CAAC"}
|
package/dest/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export * from './config.js';
|
|
|
3
3
|
export * from './publisher/index.js';
|
|
4
4
|
export * from './tx_validator/tx_validator_factory.js';
|
|
5
5
|
export * from './slasher/index.js';
|
|
6
|
-
export { Sequencer, SequencerState
|
|
6
|
+
export { Sequencer, SequencerState } from './sequencer/index.js';
|
|
7
7
|
// Used by the node to simulate public parts of transactions. Should these be moved to a shared library?
|
|
8
8
|
// ISSUE(#9832)
|
|
9
9
|
export * from './global_variable_builder/index.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sequencer/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sequencer/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC"}
|
package/dest/sequencer/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAG9C,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,EAAW,MAAM,yBAAyB,CAAC;AAC5E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ import { Fr } from '@aztec/foundation/fields';
|
|
|
11
11
|
import { createLogger } from '@aztec/foundation/log';
|
|
12
12
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
13
13
|
import { Timer, elapsed } from '@aztec/foundation/timer';
|
|
14
|
+
import { getDefaultAllowedSetupFunctions } from '@aztec/p2p/msg_validators';
|
|
14
15
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
15
16
|
import { Gas } from '@aztec/stdlib/gas';
|
|
16
17
|
import { SequencerConfigSchema } from '@aztec/stdlib/interfaces/server';
|
|
@@ -20,7 +21,6 @@ import { BlockHeader, ContentCommitment, StateReference, Tx } from '@aztec/stdli
|
|
|
20
21
|
import { Attributes, L1Metrics, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
21
22
|
import { VoteType } from '../publisher/sequencer-publisher.js';
|
|
22
23
|
import { createValidatorForBlockBuilding } from '../tx_validator/tx_validator_factory.js';
|
|
23
|
-
import { getDefaultAllowedSetupFunctions } from './allowed.js';
|
|
24
24
|
import { SequencerMetrics } from './metrics.js';
|
|
25
25
|
import { SequencerTimetable, SequencerTooSlowError } from './timetable.js';
|
|
26
26
|
import { SequencerState, orderAttestations } from './utils.js';
|
|
@@ -58,7 +58,7 @@ export { SequencerState };
|
|
|
58
58
|
_coinbase;
|
|
59
59
|
_feeRecipient;
|
|
60
60
|
state;
|
|
61
|
-
|
|
61
|
+
txPublicSetupAllowList;
|
|
62
62
|
maxBlockSizeInBytes;
|
|
63
63
|
maxBlockGas;
|
|
64
64
|
metrics;
|
|
@@ -89,7 +89,7 @@ export { SequencerState };
|
|
|
89
89
|
this._coinbase = EthAddress.ZERO;
|
|
90
90
|
this._feeRecipient = AztecAddress.ZERO;
|
|
91
91
|
this.state = SequencerState.STOPPED;
|
|
92
|
-
this.
|
|
92
|
+
this.txPublicSetupAllowList = [];
|
|
93
93
|
this.maxBlockSizeInBytes = 1024 * 1024;
|
|
94
94
|
this.maxBlockGas = new Gas(100e9, 100e9);
|
|
95
95
|
this.isFlushing = false;
|
|
@@ -113,7 +113,7 @@ export { SequencerState };
|
|
|
113
113
|
* Updates sequencer config.
|
|
114
114
|
* @param config - New parameters.
|
|
115
115
|
*/ async updateConfig(config) {
|
|
116
|
-
this.log.info(`Sequencer config set`, omit(pickFromSchema(config, SequencerConfigSchema), '
|
|
116
|
+
this.log.info(`Sequencer config set`, omit(pickFromSchema(config, SequencerConfigSchema), 'txPublicSetupAllowList'));
|
|
117
117
|
if (config.transactionPollingIntervalMS !== undefined) {
|
|
118
118
|
this.pollingIntervalMs = config.transactionPollingIntervalMS;
|
|
119
119
|
}
|
|
@@ -135,10 +135,10 @@ export { SequencerState };
|
|
|
135
135
|
if (config.feeRecipient) {
|
|
136
136
|
this._feeRecipient = config.feeRecipient;
|
|
137
137
|
}
|
|
138
|
-
if (config.
|
|
139
|
-
this.
|
|
138
|
+
if (config.txPublicSetupAllowList) {
|
|
139
|
+
this.txPublicSetupAllowList = config.txPublicSetupAllowList;
|
|
140
140
|
} else {
|
|
141
|
-
this.
|
|
141
|
+
this.txPublicSetupAllowList = await getDefaultAllowedSetupFunctions();
|
|
142
142
|
}
|
|
143
143
|
if (config.maxBlockSizeInBytes !== undefined) {
|
|
144
144
|
this.maxBlockSizeInBytes = config.maxBlockSizeInBytes;
|
|
@@ -370,7 +370,7 @@ export { SequencerState };
|
|
|
370
370
|
now: new Date(this.dateProvider.now()),
|
|
371
371
|
deadline
|
|
372
372
|
});
|
|
373
|
-
const validator = createValidatorForBlockBuilding(publicProcessorDBFork, this.contractDataSource, newGlobalVariables, this.
|
|
373
|
+
const validator = createValidatorForBlockBuilding(publicProcessorDBFork, this.contractDataSource, newGlobalVariables, this.txPublicSetupAllowList);
|
|
374
374
|
// TODO(#11000): Public processor should just handle processing, one tx at a time. It should be responsibility
|
|
375
375
|
// of the sequencer to update world state and iterate over txs. We should refactor this along with unifying the
|
|
376
376
|
// publicProcessorFork and orchestratorFork, to avoid doing tree insertions twice when building the block.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tx_validator_factory.d.ts","sourceRoot":"","sources":["../../src/tx_validator/tx_validator_factory.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"tx_validator_factory.d.ts","sourceRoot":"","sources":["../../src/tx_validator/tx_validator_factory.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EACV,cAAc,EACd,6BAA6B,EAC7B,wBAAwB,EACzB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG9E,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,wBAAwB,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,QAAQ,EAAE,6BAA6B,GAAG,SAAS,EACnD,EACE,WAAW,EACX,SAAS,EACT,aAAa,EACb,cAAc,EACd,OAAO,EACP,kBAAkB,GACnB,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,cAAc,EAAE,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,GACA,WAAW,CAAC,EAAE,CAAC,CAkBjB;AAED,wBAAgB,+BAA+B,CAC7C,EAAE,EAAE,wBAAwB,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,eAAe,EAAE,eAAe,EAChC,cAAc,EAAE,cAAc,EAAE,GAC/B;IACD,mBAAmB,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IACrC,cAAc,EAAE,cAAc,CAAC;CAChC,CAgBA"}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import { MerkleTreeId } from '@aztec/aztec.js';
|
|
2
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
-
import { AggregateTxValidator, BlockHeaderTxValidator, DataTxValidator, DoubleSpendTxValidator, MetadataTxValidator, TxProofValidator } from '@aztec/p2p';
|
|
2
|
+
import { AggregateTxValidator, BlockHeaderTxValidator, DataTxValidator, DoubleSpendTxValidator, GasTxValidator, MetadataTxValidator, PhasesTxValidator, TxProofValidator } from '@aztec/p2p';
|
|
4
3
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
5
|
-
import {
|
|
4
|
+
import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
|
|
6
5
|
import { ArchiveCache } from './archive_cache.js';
|
|
7
|
-
import { GasTxValidator } from './gas_validator.js';
|
|
8
6
|
import { NullifierCache } from './nullifier_cache.js';
|
|
9
|
-
import { PhasesTxValidator } from './phases_validator.js';
|
|
10
7
|
export function createValidatorForAcceptingTxs(db, contractDataSource, verifier, { blockNumber, l1ChainId, rollupVersion, setupAllowList, gasFees, skipFeeEnforcement }) {
|
|
11
8
|
const validators = [
|
|
12
9
|
new DataTxValidator(),
|
|
@@ -32,21 +29,6 @@ export function createValidatorForBlockBuilding(db, contractDataSource, globalVa
|
|
|
32
29
|
nullifierCache
|
|
33
30
|
};
|
|
34
31
|
}
|
|
35
|
-
class DatabasePublicStateSource {
|
|
36
|
-
db;
|
|
37
|
-
constructor(db){
|
|
38
|
-
this.db = db;
|
|
39
|
-
}
|
|
40
|
-
async storageRead(contractAddress, slot) {
|
|
41
|
-
const leafSlot = (await computePublicDataTreeLeafSlot(contractAddress, slot)).toBigInt();
|
|
42
|
-
const lowLeafResult = await this.db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
|
|
43
|
-
if (!lowLeafResult || !lowLeafResult.alreadyPresent) {
|
|
44
|
-
return Fr.ZERO;
|
|
45
|
-
}
|
|
46
|
-
const preimage = await this.db.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index);
|
|
47
|
-
return preimage.leaf.value;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
32
|
function preprocessValidator(nullifierCache, archiveCache, publicStateSource, contractDataSource, globalVariables, setupAllowList) {
|
|
51
33
|
// We don't include the TxProofValidator nor the DataTxValidator here because they are already checked by the time we get to block building.
|
|
52
34
|
return new AggregateTxValidator(new MetadataTxValidator(globalVariables.chainId, globalVariables.version, globalVariables.blockNumber), new DoubleSpendTxValidator(nullifierCache), new PhasesTxValidator(contractDataSource, setupAllowList, globalVariables.blockNumber.toNumber()), new GasTxValidator(publicStateSource, ProtocolContractAddress.FeeJuice, globalVariables.gasFees), new BlockHeaderTxValidator(archiveCache));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/sequencer-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.84.0-alpha-testnet.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -28,36 +28,36 @@
|
|
|
28
28
|
"test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --config jest.integration.config.json"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@aztec/aztec.js": "0.
|
|
32
|
-
"@aztec/bb-prover": "0.
|
|
33
|
-
"@aztec/blob-lib": "0.
|
|
34
|
-
"@aztec/blob-sink": "0.
|
|
35
|
-
"@aztec/constants": "0.
|
|
36
|
-
"@aztec/epoch-cache": "0.
|
|
37
|
-
"@aztec/ethereum": "0.
|
|
38
|
-
"@aztec/foundation": "0.
|
|
39
|
-
"@aztec/l1-artifacts": "0.
|
|
40
|
-
"@aztec/merkle-tree": "0.
|
|
41
|
-
"@aztec/noir-acvm_js": "0.
|
|
42
|
-
"@aztec/noir-contracts.js": "0.
|
|
43
|
-
"@aztec/noir-protocol-circuits-types": "0.
|
|
44
|
-
"@aztec/noir-types": "0.
|
|
45
|
-
"@aztec/p2p": "0.
|
|
46
|
-
"@aztec/protocol-contracts": "0.
|
|
47
|
-
"@aztec/prover-client": "0.
|
|
48
|
-
"@aztec/simulator": "0.
|
|
49
|
-
"@aztec/stdlib": "0.
|
|
50
|
-
"@aztec/telemetry-client": "0.
|
|
51
|
-
"@aztec/validator-client": "0.
|
|
52
|
-
"@aztec/world-state": "0.
|
|
31
|
+
"@aztec/aztec.js": "0.84.0-alpha-testnet.1",
|
|
32
|
+
"@aztec/bb-prover": "0.84.0-alpha-testnet.1",
|
|
33
|
+
"@aztec/blob-lib": "0.84.0-alpha-testnet.1",
|
|
34
|
+
"@aztec/blob-sink": "0.84.0-alpha-testnet.1",
|
|
35
|
+
"@aztec/constants": "0.84.0-alpha-testnet.1",
|
|
36
|
+
"@aztec/epoch-cache": "0.84.0-alpha-testnet.1",
|
|
37
|
+
"@aztec/ethereum": "0.84.0-alpha-testnet.1",
|
|
38
|
+
"@aztec/foundation": "0.84.0-alpha-testnet.1",
|
|
39
|
+
"@aztec/l1-artifacts": "0.84.0-alpha-testnet.1",
|
|
40
|
+
"@aztec/merkle-tree": "0.84.0-alpha-testnet.1",
|
|
41
|
+
"@aztec/noir-acvm_js": "0.84.0-alpha-testnet.1",
|
|
42
|
+
"@aztec/noir-contracts.js": "0.84.0-alpha-testnet.1",
|
|
43
|
+
"@aztec/noir-protocol-circuits-types": "0.84.0-alpha-testnet.1",
|
|
44
|
+
"@aztec/noir-types": "0.84.0-alpha-testnet.1",
|
|
45
|
+
"@aztec/p2p": "0.84.0-alpha-testnet.1",
|
|
46
|
+
"@aztec/protocol-contracts": "0.84.0-alpha-testnet.1",
|
|
47
|
+
"@aztec/prover-client": "0.84.0-alpha-testnet.1",
|
|
48
|
+
"@aztec/simulator": "0.84.0-alpha-testnet.1",
|
|
49
|
+
"@aztec/stdlib": "0.84.0-alpha-testnet.1",
|
|
50
|
+
"@aztec/telemetry-client": "0.84.0-alpha-testnet.1",
|
|
51
|
+
"@aztec/validator-client": "0.84.0-alpha-testnet.1",
|
|
52
|
+
"@aztec/world-state": "0.84.0-alpha-testnet.1",
|
|
53
53
|
"lodash.chunk": "^4.2.0",
|
|
54
54
|
"lodash.pick": "^4.4.0",
|
|
55
55
|
"tslib": "^2.4.0",
|
|
56
56
|
"viem": "2.23.7"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@aztec/archiver": "0.
|
|
60
|
-
"@aztec/kv-store": "0.
|
|
59
|
+
"@aztec/archiver": "0.84.0-alpha-testnet.1",
|
|
60
|
+
"@aztec/kv-store": "0.84.0-alpha-testnet.1",
|
|
61
61
|
"@jest/globals": "^29.5.0",
|
|
62
62
|
"@types/jest": "^29.5.0",
|
|
63
63
|
"@types/levelup": "^5.1.2",
|
package/src/config.ts
CHANGED
|
@@ -12,10 +12,9 @@ import {
|
|
|
12
12
|
pickConfigMappings,
|
|
13
13
|
} from '@aztec/foundation/config';
|
|
14
14
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
15
|
-
import {
|
|
16
|
-
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
15
|
+
import { type P2PConfig, p2pConfigMappings } from '@aztec/p2p';
|
|
17
16
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
18
|
-
import { type
|
|
17
|
+
import { type ChainConfig, type SequencerConfig, chainConfigMappings } from '@aztec/stdlib/config';
|
|
19
18
|
import { type ValidatorClientConfig, validatorClientConfigMappings } from '@aztec/validator-client';
|
|
20
19
|
|
|
21
20
|
import {
|
|
@@ -37,6 +36,7 @@ export type SequencerClientConfig = PublisherConfig &
|
|
|
37
36
|
SequencerConfig &
|
|
38
37
|
L1ReaderConfig &
|
|
39
38
|
ChainConfig &
|
|
39
|
+
Pick<P2PConfig, 'txPublicSetupAllowList'> &
|
|
40
40
|
Pick<L1ContractsConfig, 'ethereumSlotDuration' | 'aztecSlotDuration' | 'aztecEpochDuration'>;
|
|
41
41
|
|
|
42
42
|
export const sequencerConfigMappings: ConfigMappingsType<SequencerConfig> = {
|
|
@@ -83,13 +83,6 @@ export const sequencerConfigMappings: ConfigMappingsType<SequencerConfig> = {
|
|
|
83
83
|
env: 'ACVM_BINARY_PATH',
|
|
84
84
|
description: 'The path to the ACVM binary',
|
|
85
85
|
},
|
|
86
|
-
allowedInSetup: {
|
|
87
|
-
env: 'SEQ_ALLOWED_SETUP_FN',
|
|
88
|
-
parseEnv: (val: string) => parseSequencerAllowList(val),
|
|
89
|
-
description: 'The list of functions calls allowed to run in setup',
|
|
90
|
-
printDefault: () =>
|
|
91
|
-
'AuthRegistry, FeeJuice.increase_public_balance, Token.increase_public_balance, FPC.prepare_fee',
|
|
92
|
-
},
|
|
93
86
|
maxBlockSizeInBytes: {
|
|
94
87
|
env: 'SEQ_MAX_BLOCK_SIZE_IN_BYTES',
|
|
95
88
|
description: 'Max block size',
|
|
@@ -112,6 +105,7 @@ export const sequencerConfigMappings: ConfigMappingsType<SequencerConfig> = {
|
|
|
112
105
|
description: 'How many seconds into an L1 slot we can still send a tx and get it mined.',
|
|
113
106
|
parseEnv: (val: string) => (val ? parseInt(val, 10) : undefined),
|
|
114
107
|
},
|
|
108
|
+
...pickConfigMappings(p2pConfigMappings, ['txPublicSetupAllowList']),
|
|
115
109
|
};
|
|
116
110
|
|
|
117
111
|
export const sequencerClientConfigMappings: ConfigMappingsType<SequencerClientConfig> = {
|
|
@@ -130,53 +124,3 @@ export const sequencerClientConfigMappings: ConfigMappingsType<SequencerClientCo
|
|
|
130
124
|
export function getConfigEnvVars(): SequencerClientConfig {
|
|
131
125
|
return getConfigFromMappings<SequencerClientConfig>(sequencerClientConfigMappings);
|
|
132
126
|
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Parses a string to a list of allowed elements.
|
|
136
|
-
* Each encoded is expected to be of one of the following formats
|
|
137
|
-
* `I:${address}`
|
|
138
|
-
* `I:${address}:${selector}`
|
|
139
|
-
* `C:${classId}`
|
|
140
|
-
* `C:${classId}:${selector}`
|
|
141
|
-
*
|
|
142
|
-
* @param value The string to parse
|
|
143
|
-
* @returns A list of allowed elements
|
|
144
|
-
*/
|
|
145
|
-
export function parseSequencerAllowList(value: string): AllowedElement[] {
|
|
146
|
-
const entries: AllowedElement[] = [];
|
|
147
|
-
|
|
148
|
-
if (!value) {
|
|
149
|
-
return entries;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
for (const val of value.split(',')) {
|
|
153
|
-
const [typeString, identifierString, selectorString] = val.split(':');
|
|
154
|
-
const selector = selectorString !== undefined ? FunctionSelector.fromString(selectorString) : undefined;
|
|
155
|
-
|
|
156
|
-
if (typeString === 'I') {
|
|
157
|
-
if (selector) {
|
|
158
|
-
entries.push({
|
|
159
|
-
address: AztecAddress.fromString(identifierString),
|
|
160
|
-
selector,
|
|
161
|
-
});
|
|
162
|
-
} else {
|
|
163
|
-
entries.push({
|
|
164
|
-
address: AztecAddress.fromString(identifierString),
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
} else if (typeString === 'C') {
|
|
168
|
-
if (selector) {
|
|
169
|
-
entries.push({
|
|
170
|
-
classId: Fr.fromHexString(identifierString),
|
|
171
|
-
selector,
|
|
172
|
-
});
|
|
173
|
-
} else {
|
|
174
|
-
entries.push({
|
|
175
|
-
classId: Fr.fromHexString(identifierString),
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return entries;
|
|
182
|
-
}
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ export * from './config.js';
|
|
|
3
3
|
export * from './publisher/index.js';
|
|
4
4
|
export * from './tx_validator/tx_validator_factory.js';
|
|
5
5
|
export * from './slasher/index.js';
|
|
6
|
-
export { Sequencer, SequencerState
|
|
6
|
+
export { Sequencer, SequencerState } from './sequencer/index.js';
|
|
7
7
|
|
|
8
8
|
// Used by the node to simulate public parts of transactions. Should these be moved to a shared library?
|
|
9
9
|
// ISSUE(#9832)
|
package/src/sequencer/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
8
8
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
9
9
|
import { type DateProvider, Timer, elapsed } from '@aztec/foundation/timer';
|
|
10
10
|
import type { P2P } from '@aztec/p2p';
|
|
11
|
+
import { getDefaultAllowedSetupFunctions } from '@aztec/p2p/msg_validators';
|
|
11
12
|
import type { BlockBuilderFactory } from '@aztec/prover-client/block-builder';
|
|
12
13
|
import type { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
13
14
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
@@ -47,7 +48,6 @@ import type { GlobalVariableBuilder } from '../global_variable_builder/global_bu
|
|
|
47
48
|
import { type SequencerPublisher, VoteType } from '../publisher/sequencer-publisher.js';
|
|
48
49
|
import type { SlasherClient } from '../slasher/slasher_client.js';
|
|
49
50
|
import { createValidatorForBlockBuilding } from '../tx_validator/tx_validator_factory.js';
|
|
50
|
-
import { getDefaultAllowedSetupFunctions } from './allowed.js';
|
|
51
51
|
import type { SequencerConfig } from './config.js';
|
|
52
52
|
import { SequencerMetrics } from './metrics.js';
|
|
53
53
|
import { SequencerTimetable, SequencerTooSlowError } from './timetable.js';
|
|
@@ -76,7 +76,7 @@ export class Sequencer {
|
|
|
76
76
|
private _coinbase = EthAddress.ZERO;
|
|
77
77
|
private _feeRecipient = AztecAddress.ZERO;
|
|
78
78
|
private state = SequencerState.STOPPED;
|
|
79
|
-
private
|
|
79
|
+
private txPublicSetupAllowList: AllowedElement[] = [];
|
|
80
80
|
private maxBlockSizeInBytes: number = 1024 * 1024;
|
|
81
81
|
private maxBlockGas: Gas = new Gas(100e9, 100e9);
|
|
82
82
|
private metrics: SequencerMetrics;
|
|
@@ -131,7 +131,10 @@ export class Sequencer {
|
|
|
131
131
|
* @param config - New parameters.
|
|
132
132
|
*/
|
|
133
133
|
public async updateConfig(config: SequencerConfig) {
|
|
134
|
-
this.log.info(
|
|
134
|
+
this.log.info(
|
|
135
|
+
`Sequencer config set`,
|
|
136
|
+
omit(pickFromSchema(config, SequencerConfigSchema), 'txPublicSetupAllowList'),
|
|
137
|
+
);
|
|
135
138
|
|
|
136
139
|
if (config.transactionPollingIntervalMS !== undefined) {
|
|
137
140
|
this.pollingIntervalMs = config.transactionPollingIntervalMS;
|
|
@@ -154,10 +157,10 @@ export class Sequencer {
|
|
|
154
157
|
if (config.feeRecipient) {
|
|
155
158
|
this._feeRecipient = config.feeRecipient;
|
|
156
159
|
}
|
|
157
|
-
if (config.
|
|
158
|
-
this.
|
|
160
|
+
if (config.txPublicSetupAllowList) {
|
|
161
|
+
this.txPublicSetupAllowList = config.txPublicSetupAllowList;
|
|
159
162
|
} else {
|
|
160
|
-
this.
|
|
163
|
+
this.txPublicSetupAllowList = await getDefaultAllowedSetupFunctions();
|
|
161
164
|
}
|
|
162
165
|
if (config.maxBlockSizeInBytes !== undefined) {
|
|
163
166
|
this.maxBlockSizeInBytes = config.maxBlockSizeInBytes;
|
|
@@ -469,7 +472,7 @@ export class Sequencer {
|
|
|
469
472
|
publicProcessorDBFork,
|
|
470
473
|
this.contractDataSource,
|
|
471
474
|
newGlobalVariables,
|
|
472
|
-
this.
|
|
475
|
+
this.txPublicSetupAllowList,
|
|
473
476
|
);
|
|
474
477
|
|
|
475
478
|
// TODO(#11000): Public processor should just handle processing, one tx at a time. It should be responsibility
|
|
@@ -1,30 +1,27 @@
|
|
|
1
|
-
import { MerkleTreeId } from '@aztec/aztec.js';
|
|
2
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
2
|
import {
|
|
4
3
|
AggregateTxValidator,
|
|
5
4
|
BlockHeaderTxValidator,
|
|
6
5
|
DataTxValidator,
|
|
7
6
|
DoubleSpendTxValidator,
|
|
7
|
+
GasTxValidator,
|
|
8
8
|
MetadataTxValidator,
|
|
9
|
+
PhasesTxValidator,
|
|
9
10
|
TxProofValidator,
|
|
10
11
|
} from '@aztec/p2p';
|
|
11
12
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
12
|
-
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
13
13
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
14
14
|
import type { GasFees } from '@aztec/stdlib/gas';
|
|
15
|
-
import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
|
|
16
15
|
import type {
|
|
17
16
|
AllowedElement,
|
|
18
17
|
ClientProtocolCircuitVerifier,
|
|
19
18
|
MerkleTreeReadOperations,
|
|
20
19
|
} from '@aztec/stdlib/interfaces/server';
|
|
21
|
-
import type
|
|
20
|
+
import { DatabasePublicStateSource, type PublicStateSource } from '@aztec/stdlib/trees';
|
|
22
21
|
import { GlobalVariables, type Tx, type TxValidator } from '@aztec/stdlib/tx';
|
|
23
22
|
|
|
24
23
|
import { ArchiveCache } from './archive_cache.js';
|
|
25
|
-
import { GasTxValidator, type PublicStateSource } from './gas_validator.js';
|
|
26
24
|
import { NullifierCache } from './nullifier_cache.js';
|
|
27
|
-
import { PhasesTxValidator } from './phases_validator.js';
|
|
28
25
|
|
|
29
26
|
export function createValidatorForAcceptingTxs(
|
|
30
27
|
db: MerkleTreeReadOperations,
|
|
@@ -91,26 +88,6 @@ export function createValidatorForBlockBuilding(
|
|
|
91
88
|
};
|
|
92
89
|
}
|
|
93
90
|
|
|
94
|
-
class DatabasePublicStateSource implements PublicStateSource {
|
|
95
|
-
constructor(private db: MerkleTreeReadOperations) {}
|
|
96
|
-
|
|
97
|
-
async storageRead(contractAddress: AztecAddress, slot: Fr): Promise<Fr> {
|
|
98
|
-
const leafSlot = (await computePublicDataTreeLeafSlot(contractAddress, slot)).toBigInt();
|
|
99
|
-
|
|
100
|
-
const lowLeafResult = await this.db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
|
|
101
|
-
if (!lowLeafResult || !lowLeafResult.alreadyPresent) {
|
|
102
|
-
return Fr.ZERO;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const preimage = (await this.db.getLeafPreimage(
|
|
106
|
-
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
107
|
-
lowLeafResult.index,
|
|
108
|
-
)) as PublicDataTreeLeafPreimage;
|
|
109
|
-
|
|
110
|
-
return preimage.leaf.value;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
91
|
function preprocessValidator(
|
|
115
92
|
nullifierCache: NullifierCache,
|
|
116
93
|
archiveCache: ArchiveCache,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"allowed.d.ts","sourceRoot":"","sources":["../../src/sequencer/allowed.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAItE,wBAAsB,+BAA+B,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CA2BjF"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { FPCContract } from '@aztec/noir-contracts.js/FPC';
|
|
2
|
-
import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
|
|
3
|
-
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
4
|
-
import { getContractClassFromArtifact } from '@aztec/stdlib/contract';
|
|
5
|
-
let defaultAllowedSetupFunctions = undefined;
|
|
6
|
-
export async function getDefaultAllowedSetupFunctions() {
|
|
7
|
-
if (defaultAllowedSetupFunctions === undefined) {
|
|
8
|
-
defaultAllowedSetupFunctions = [
|
|
9
|
-
// needed for authwit support
|
|
10
|
-
{
|
|
11
|
-
address: ProtocolContractAddress.AuthRegistry
|
|
12
|
-
},
|
|
13
|
-
// needed for claiming on the same tx as a spend
|
|
14
|
-
{
|
|
15
|
-
address: ProtocolContractAddress.FeeJuice
|
|
16
|
-
},
|
|
17
|
-
// needed for private transfers via FPC
|
|
18
|
-
{
|
|
19
|
-
classId: (await getContractClassFromArtifact(TokenContractArtifact)).id
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
classId: (await getContractClassFromArtifact(FPCContract.artifact)).id
|
|
23
|
-
}
|
|
24
|
-
];
|
|
25
|
-
}
|
|
26
|
-
return defaultAllowedSetupFunctions;
|
|
27
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
-
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
3
|
-
import type { GasFees } from '@aztec/stdlib/gas';
|
|
4
|
-
import { type Tx, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
|
|
5
|
-
/** Provides a view into public contract state */
|
|
6
|
-
export interface PublicStateSource {
|
|
7
|
-
storageRead: (contractAddress: AztecAddress, slot: Fr) => Promise<Fr>;
|
|
8
|
-
}
|
|
9
|
-
export declare class GasTxValidator implements TxValidator<Tx> {
|
|
10
|
-
#private;
|
|
11
|
-
constructor(publicDataSource: PublicStateSource, feeJuiceAddress: AztecAddress, gasFees: GasFees);
|
|
12
|
-
validateTx(tx: Tx): Promise<TxValidationResult>;
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=gas_validator.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gas_validator.d.ts","sourceRoot":"","sources":["../../src/tx_validator/gas_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAK9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,EAAoB,KAAK,kBAAkB,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAExG,iDAAiD;AACjD,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC,CAAC;CACvE;AAED,qBAAa,cAAe,YAAW,WAAW,CAAC,EAAE,CAAC;;gBAMxC,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO;IAM1F,UAAU,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAyEtD"}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
-
import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
|
|
3
|
-
import { getCallRequestsWithCalldataByPhase } from '@aztec/simulator/server';
|
|
4
|
-
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
5
|
-
import { TxExecutionPhase } from '@aztec/stdlib/tx';
|
|
6
|
-
export class GasTxValidator {
|
|
7
|
-
#log = createLogger('sequencer:tx_validator:tx_gas');
|
|
8
|
-
#publicDataSource;
|
|
9
|
-
#feeJuiceAddress;
|
|
10
|
-
#gasFees;
|
|
11
|
-
constructor(publicDataSource, feeJuiceAddress, gasFees){
|
|
12
|
-
this.#publicDataSource = publicDataSource;
|
|
13
|
-
this.#feeJuiceAddress = feeJuiceAddress;
|
|
14
|
-
this.#gasFees = gasFees;
|
|
15
|
-
}
|
|
16
|
-
async validateTx(tx) {
|
|
17
|
-
if (await this.#shouldSkip(tx)) {
|
|
18
|
-
return Promise.resolve({
|
|
19
|
-
result: 'skipped',
|
|
20
|
-
reason: [
|
|
21
|
-
'Insufficient fee per gas'
|
|
22
|
-
]
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
return this.#validateTxFee(tx);
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Check whether the tx's max fees are valid for the current block, and skip if not.
|
|
29
|
-
* We skip instead of invalidating since the tx may become eligible later.
|
|
30
|
-
* Note that circuits check max fees even if fee payer is unset, so we
|
|
31
|
-
* keep this validation even if the tx does not pay fees.
|
|
32
|
-
*/ async #shouldSkip(tx) {
|
|
33
|
-
const gasSettings = tx.data.constants.txContext.gasSettings;
|
|
34
|
-
// Skip the tx if its max fees are not enough for the current block's gas fees.
|
|
35
|
-
const maxFeesPerGas = gasSettings.maxFeesPerGas;
|
|
36
|
-
const notEnoughMaxFees = maxFeesPerGas.feePerDaGas.lt(this.#gasFees.feePerDaGas) || maxFeesPerGas.feePerL2Gas.lt(this.#gasFees.feePerL2Gas);
|
|
37
|
-
if (notEnoughMaxFees) {
|
|
38
|
-
this.#log.warn(`Skipping transaction ${await tx.getTxHash()} due to insufficient fee per gas`, {
|
|
39
|
-
txMaxFeesPerGas: maxFeesPerGas.toInspect(),
|
|
40
|
-
currentGasFees: this.#gasFees.toInspect()
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
return notEnoughMaxFees;
|
|
44
|
-
}
|
|
45
|
-
async #validateTxFee(tx) {
|
|
46
|
-
const feePayer = tx.data.feePayer;
|
|
47
|
-
// Compute the maximum fee that this tx may pay, based on its gasLimits and maxFeePerGas
|
|
48
|
-
const feeLimit = tx.data.constants.txContext.gasSettings.getFeeLimit();
|
|
49
|
-
// Read current balance of the feePayer
|
|
50
|
-
const initialBalance = await this.#publicDataSource.storageRead(this.#feeJuiceAddress, await computeFeePayerBalanceStorageSlot(feePayer));
|
|
51
|
-
// If there is a claim in this tx that increases the fee payer balance in Fee Juice, add it to balance
|
|
52
|
-
const setupFns = getCallRequestsWithCalldataByPhase(tx, TxExecutionPhase.SETUP);
|
|
53
|
-
const increasePublicBalanceSelector = await FunctionSelector.fromSignature('_increase_public_balance((Field),u128)');
|
|
54
|
-
// Arguments of the claim function call:
|
|
55
|
-
// - args[0]: Amount recipient.
|
|
56
|
-
// - args[1]: Amount being claimed.
|
|
57
|
-
const claimFunctionCall = setupFns.find((fn)=>fn.request.contractAddress.equals(this.#feeJuiceAddress) && fn.request.msgSender.equals(this.#feeJuiceAddress) && fn.calldata.length > 2 && fn.functionSelector.equals(increasePublicBalanceSelector) && fn.args[0].equals(feePayer.toField()) && !fn.request.isStaticCall);
|
|
58
|
-
const balance = claimFunctionCall ? initialBalance.add(claimFunctionCall.args[1]) : initialBalance;
|
|
59
|
-
if (balance.lt(feeLimit)) {
|
|
60
|
-
this.#log.warn(`Rejecting transaction due to not enough fee payer balance`, {
|
|
61
|
-
feePayer,
|
|
62
|
-
balance: balance.toBigInt(),
|
|
63
|
-
feeLimit: feeLimit.toBigInt()
|
|
64
|
-
});
|
|
65
|
-
return {
|
|
66
|
-
result: 'invalid',
|
|
67
|
-
reason: [
|
|
68
|
-
'Insufficient fee payer balance'
|
|
69
|
-
]
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
return {
|
|
73
|
-
result: 'valid'
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
2
|
-
import type { AllowedElement } from '@aztec/stdlib/interfaces/server';
|
|
3
|
-
import { Tx, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
|
|
4
|
-
export declare class PhasesTxValidator implements TxValidator<Tx> {
|
|
5
|
-
#private;
|
|
6
|
-
private setupAllowList;
|
|
7
|
-
private blockNumber;
|
|
8
|
-
private contractsDB;
|
|
9
|
-
constructor(contracts: ContractDataSource, setupAllowList: AllowedElement[], blockNumber: number);
|
|
10
|
-
validateTx(tx: Tx): Promise<TxValidationResult>;
|
|
11
|
-
private isOnAllowList;
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=phases_validator.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"phases_validator.d.ts","sourceRoot":"","sources":["../../src/tx_validator/phases_validator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAEL,EAAE,EAEF,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,kBAAkB,CAAC;AAE1B,qBAAa,iBAAkB,YAAW,WAAW,CAAC,EAAE,CAAC;;IAIZ,OAAO,CAAC,cAAc;IAAoB,OAAO,CAAC,WAAW;IAFxG,OAAO,CAAC,WAAW,CAAoB;gBAE3B,SAAS,EAAE,kBAAkB,EAAU,cAAc,EAAE,cAAc,EAAE,EAAU,WAAW,EAAE,MAAM;IAI1G,UAAU,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC;YAkCvC,aAAa;CAiD5B"}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
-
import { PublicContractsDB, getCallRequestsWithCalldataByPhase } from '@aztec/simulator/server';
|
|
3
|
-
import { Tx, TxExecutionPhase } from '@aztec/stdlib/tx';
|
|
4
|
-
export class PhasesTxValidator {
|
|
5
|
-
setupAllowList;
|
|
6
|
-
blockNumber;
|
|
7
|
-
#log;
|
|
8
|
-
contractsDB;
|
|
9
|
-
constructor(contracts, setupAllowList, blockNumber){
|
|
10
|
-
this.setupAllowList = setupAllowList;
|
|
11
|
-
this.blockNumber = blockNumber;
|
|
12
|
-
this.#log = createLogger('sequencer:tx_validator:tx_phases');
|
|
13
|
-
this.contractsDB = new PublicContractsDB(contracts);
|
|
14
|
-
}
|
|
15
|
-
async validateTx(tx) {
|
|
16
|
-
try {
|
|
17
|
-
// TODO(@spalladino): We add this just to handle public authwit-check calls during setup
|
|
18
|
-
// which are needed for public FPC flows, but fail if the account contract hasnt been deployed yet,
|
|
19
|
-
// which is what we're trying to do as part of the current txs.
|
|
20
|
-
await this.contractsDB.addNewContracts(tx);
|
|
21
|
-
if (!tx.data.forPublic) {
|
|
22
|
-
this.#log.debug(`Tx ${await Tx.getHash(tx)} does not contain enqueued public functions. Skipping phases validation.`);
|
|
23
|
-
return {
|
|
24
|
-
result: 'valid'
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
const setupFns = getCallRequestsWithCalldataByPhase(tx, TxExecutionPhase.SETUP);
|
|
28
|
-
for (const setupFn of setupFns){
|
|
29
|
-
if (!await this.isOnAllowList(setupFn, this.setupAllowList)) {
|
|
30
|
-
this.#log.warn(`Rejecting tx ${await Tx.getHash(tx)} because it calls setup function not on allow list: ${setupFn.request.contractAddress}:${setupFn.functionSelector}`, {
|
|
31
|
-
allowList: this.setupAllowList
|
|
32
|
-
});
|
|
33
|
-
return {
|
|
34
|
-
result: 'invalid',
|
|
35
|
-
reason: [
|
|
36
|
-
'Setup function not on allow list'
|
|
37
|
-
]
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return {
|
|
42
|
-
result: 'valid'
|
|
43
|
-
};
|
|
44
|
-
} finally{
|
|
45
|
-
this.contractsDB.clearContractsForTx();
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
async isOnAllowList(publicCall, allowList) {
|
|
49
|
-
if (publicCall.isEmpty()) {
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
const contractAddress = publicCall.request.contractAddress;
|
|
53
|
-
const functionSelector = publicCall.functionSelector;
|
|
54
|
-
// do these checks first since they don't require the contract class
|
|
55
|
-
for (const entry of allowList){
|
|
56
|
-
if ('address' in entry && !('selector' in entry)) {
|
|
57
|
-
if (contractAddress.equals(entry.address)) {
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
if ('address' in entry && 'selector' in entry) {
|
|
62
|
-
if (contractAddress.equals(entry.address) && entry.selector.equals(functionSelector)) {
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
const contractClass = await this.contractsDB.getContractInstance(contractAddress, this.blockNumber);
|
|
67
|
-
if (!contractClass) {
|
|
68
|
-
throw new Error(`Contract not found: ${contractAddress}`);
|
|
69
|
-
}
|
|
70
|
-
if ('classId' in entry && !('selector' in entry)) {
|
|
71
|
-
if (contractClass.currentContractClassId.equals(entry.classId)) {
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
if ('classId' in entry && 'selector' in entry) {
|
|
76
|
-
if (contractClass.currentContractClassId.equals(entry.classId) && (entry.selector === undefined || entry.selector.equals(functionSelector))) {
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { Fr } from '@aztec/foundation/fields';
|
|
2
|
-
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
3
|
-
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
|
-
import { type Tx } from '@aztec/stdlib/tx';
|
|
5
|
-
export declare function patchNonRevertibleFn(tx: Tx, index: number, overrides: {
|
|
6
|
-
address?: AztecAddress;
|
|
7
|
-
selector: FunctionSelector;
|
|
8
|
-
args?: Fr[];
|
|
9
|
-
msgSender?: AztecAddress;
|
|
10
|
-
}): Promise<AztecAddress>;
|
|
11
|
-
export declare function patchRevertibleFn(tx: Tx, index: number, overrides: {
|
|
12
|
-
address?: AztecAddress;
|
|
13
|
-
selector: FunctionSelector;
|
|
14
|
-
args?: Fr[];
|
|
15
|
-
msgSender?: AztecAddress;
|
|
16
|
-
}): Promise<AztecAddress>;
|
|
17
|
-
//# sourceMappingURL=test_utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test_utils.d.ts","sourceRoot":"","sources":["../../src/tx_validator/test_utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAgB,KAAK,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAEzD,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,EAAE,EACN,KAAK,EAAE,MAAM,EACb,SAAS,EAAE;IAAE,OAAO,CAAC,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,gBAAgB,CAAC;IAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,YAAY,CAAA;CAAE,GACvG,OAAO,CAAC,YAAY,CAAC,CAEvB;AAED,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,EAAE,EACN,KAAK,EAAE,MAAM,EACb,SAAS,EAAE;IAAE,OAAO,CAAC,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,gBAAgB,CAAC;IAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,YAAY,CAAA;CAAE,GACvG,OAAO,CAAC,YAAY,CAAC,CAEvB"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { HashedValues } from '@aztec/stdlib/tx';
|
|
2
|
-
export function patchNonRevertibleFn(tx, index, overrides) {
|
|
3
|
-
return patchFn('nonRevertibleAccumulatedData', tx, index, overrides);
|
|
4
|
-
}
|
|
5
|
-
export function patchRevertibleFn(tx, index, overrides) {
|
|
6
|
-
return patchFn('revertibleAccumulatedData', tx, index, overrides);
|
|
7
|
-
}
|
|
8
|
-
async function patchFn(where, tx, index, overrides) {
|
|
9
|
-
const calldataIndex = where === 'nonRevertibleAccumulatedData' ? index : index + tx.data.forPublic.nonRevertibleAccumulatedData.publicCallRequests.length;
|
|
10
|
-
const calldata = [
|
|
11
|
-
overrides.selector.toField(),
|
|
12
|
-
...overrides.args ?? []
|
|
13
|
-
];
|
|
14
|
-
const hashedCalldata = await HashedValues.fromCalldata(calldata);
|
|
15
|
-
tx.publicFunctionCalldata[calldataIndex] = hashedCalldata;
|
|
16
|
-
const request = tx.data.forPublic[where].publicCallRequests[index];
|
|
17
|
-
request.contractAddress = overrides.address ?? request.contractAddress;
|
|
18
|
-
request.msgSender = overrides.msgSender ?? request.msgSender;
|
|
19
|
-
request.calldataHash = hashedCalldata.hash;
|
|
20
|
-
tx.data.forPublic[where].publicCallRequests[index] = request;
|
|
21
|
-
return request.contractAddress;
|
|
22
|
-
}
|
package/src/sequencer/allowed.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { FPCContract } from '@aztec/noir-contracts.js/FPC';
|
|
2
|
-
import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
|
|
3
|
-
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
4
|
-
import { getContractClassFromArtifact } from '@aztec/stdlib/contract';
|
|
5
|
-
import type { AllowedElement } from '@aztec/stdlib/interfaces/server';
|
|
6
|
-
|
|
7
|
-
let defaultAllowedSetupFunctions: AllowedElement[] | undefined = undefined;
|
|
8
|
-
|
|
9
|
-
export async function getDefaultAllowedSetupFunctions(): Promise<AllowedElement[]> {
|
|
10
|
-
if (defaultAllowedSetupFunctions === undefined) {
|
|
11
|
-
defaultAllowedSetupFunctions = [
|
|
12
|
-
// needed for authwit support
|
|
13
|
-
{
|
|
14
|
-
address: ProtocolContractAddress.AuthRegistry,
|
|
15
|
-
},
|
|
16
|
-
// needed for claiming on the same tx as a spend
|
|
17
|
-
{
|
|
18
|
-
address: ProtocolContractAddress.FeeJuice,
|
|
19
|
-
// We can't restrict the selector because public functions get routed via dispatch.
|
|
20
|
-
// selector: FunctionSelector.fromSignature('_increase_public_balance((Field),u128)'),
|
|
21
|
-
},
|
|
22
|
-
// needed for private transfers via FPC
|
|
23
|
-
{
|
|
24
|
-
classId: (await getContractClassFromArtifact(TokenContractArtifact)).id,
|
|
25
|
-
// We can't restrict the selector because public functions get routed via dispatch.
|
|
26
|
-
// selector: FunctionSelector.fromSignature('_increase_public_balance((Field),u128)'),
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
classId: (await getContractClassFromArtifact(FPCContract.artifact)).id,
|
|
30
|
-
// We can't restrict the selector because public functions get routed via dispatch.
|
|
31
|
-
// selector: FunctionSelector.fromSignature('prepare_fee((Field),Field,(Field),Field)'),
|
|
32
|
-
},
|
|
33
|
-
];
|
|
34
|
-
}
|
|
35
|
-
return defaultAllowedSetupFunctions;
|
|
36
|
-
}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
-
import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
|
|
4
|
-
import { getCallRequestsWithCalldataByPhase } from '@aztec/simulator/server';
|
|
5
|
-
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
6
|
-
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
7
|
-
import type { GasFees } from '@aztec/stdlib/gas';
|
|
8
|
-
import { type Tx, TxExecutionPhase, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
|
|
9
|
-
|
|
10
|
-
/** Provides a view into public contract state */
|
|
11
|
-
export interface PublicStateSource {
|
|
12
|
-
storageRead: (contractAddress: AztecAddress, slot: Fr) => Promise<Fr>;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export class GasTxValidator implements TxValidator<Tx> {
|
|
16
|
-
#log = createLogger('sequencer:tx_validator:tx_gas');
|
|
17
|
-
#publicDataSource: PublicStateSource;
|
|
18
|
-
#feeJuiceAddress: AztecAddress;
|
|
19
|
-
#gasFees: GasFees;
|
|
20
|
-
|
|
21
|
-
constructor(publicDataSource: PublicStateSource, feeJuiceAddress: AztecAddress, gasFees: GasFees) {
|
|
22
|
-
this.#publicDataSource = publicDataSource;
|
|
23
|
-
this.#feeJuiceAddress = feeJuiceAddress;
|
|
24
|
-
this.#gasFees = gasFees;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async validateTx(tx: Tx): Promise<TxValidationResult> {
|
|
28
|
-
if (await this.#shouldSkip(tx)) {
|
|
29
|
-
return Promise.resolve({ result: 'skipped', reason: ['Insufficient fee per gas'] });
|
|
30
|
-
}
|
|
31
|
-
return this.#validateTxFee(tx);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Check whether the tx's max fees are valid for the current block, and skip if not.
|
|
36
|
-
* We skip instead of invalidating since the tx may become eligible later.
|
|
37
|
-
* Note that circuits check max fees even if fee payer is unset, so we
|
|
38
|
-
* keep this validation even if the tx does not pay fees.
|
|
39
|
-
*/
|
|
40
|
-
async #shouldSkip(tx: Tx): Promise<boolean> {
|
|
41
|
-
const gasSettings = tx.data.constants.txContext.gasSettings;
|
|
42
|
-
|
|
43
|
-
// Skip the tx if its max fees are not enough for the current block's gas fees.
|
|
44
|
-
const maxFeesPerGas = gasSettings.maxFeesPerGas;
|
|
45
|
-
const notEnoughMaxFees =
|
|
46
|
-
maxFeesPerGas.feePerDaGas.lt(this.#gasFees.feePerDaGas) ||
|
|
47
|
-
maxFeesPerGas.feePerL2Gas.lt(this.#gasFees.feePerL2Gas);
|
|
48
|
-
|
|
49
|
-
if (notEnoughMaxFees) {
|
|
50
|
-
this.#log.warn(`Skipping transaction ${await tx.getTxHash()} due to insufficient fee per gas`, {
|
|
51
|
-
txMaxFeesPerGas: maxFeesPerGas.toInspect(),
|
|
52
|
-
currentGasFees: this.#gasFees.toInspect(),
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
return notEnoughMaxFees;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async #validateTxFee(tx: Tx): Promise<TxValidationResult> {
|
|
59
|
-
const feePayer = tx.data.feePayer;
|
|
60
|
-
|
|
61
|
-
// Compute the maximum fee that this tx may pay, based on its gasLimits and maxFeePerGas
|
|
62
|
-
const feeLimit = tx.data.constants.txContext.gasSettings.getFeeLimit();
|
|
63
|
-
|
|
64
|
-
// Read current balance of the feePayer
|
|
65
|
-
const initialBalance = await this.#publicDataSource.storageRead(
|
|
66
|
-
this.#feeJuiceAddress,
|
|
67
|
-
await computeFeePayerBalanceStorageSlot(feePayer),
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
// If there is a claim in this tx that increases the fee payer balance in Fee Juice, add it to balance
|
|
71
|
-
const setupFns = getCallRequestsWithCalldataByPhase(tx, TxExecutionPhase.SETUP);
|
|
72
|
-
const increasePublicBalanceSelector = await FunctionSelector.fromSignature(
|
|
73
|
-
'_increase_public_balance((Field),u128)',
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
// Arguments of the claim function call:
|
|
77
|
-
// - args[0]: Amount recipient.
|
|
78
|
-
// - args[1]: Amount being claimed.
|
|
79
|
-
const claimFunctionCall = setupFns.find(
|
|
80
|
-
fn =>
|
|
81
|
-
fn.request.contractAddress.equals(this.#feeJuiceAddress) &&
|
|
82
|
-
fn.request.msgSender.equals(this.#feeJuiceAddress) &&
|
|
83
|
-
fn.calldata.length > 2 &&
|
|
84
|
-
fn.functionSelector.equals(increasePublicBalanceSelector) &&
|
|
85
|
-
fn.args[0].equals(feePayer.toField()) &&
|
|
86
|
-
!fn.request.isStaticCall,
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
const balance = claimFunctionCall ? initialBalance.add(claimFunctionCall.args[1]) : initialBalance;
|
|
90
|
-
if (balance.lt(feeLimit)) {
|
|
91
|
-
this.#log.warn(`Rejecting transaction due to not enough fee payer balance`, {
|
|
92
|
-
feePayer,
|
|
93
|
-
balance: balance.toBigInt(),
|
|
94
|
-
feeLimit: feeLimit.toBigInt(),
|
|
95
|
-
});
|
|
96
|
-
return { result: 'invalid', reason: ['Insufficient fee payer balance'] };
|
|
97
|
-
}
|
|
98
|
-
return { result: 'valid' };
|
|
99
|
-
}
|
|
100
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
-
import { PublicContractsDB, getCallRequestsWithCalldataByPhase } from '@aztec/simulator/server';
|
|
3
|
-
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
4
|
-
import type { AllowedElement } from '@aztec/stdlib/interfaces/server';
|
|
5
|
-
import {
|
|
6
|
-
PublicCallRequestWithCalldata,
|
|
7
|
-
Tx,
|
|
8
|
-
TxExecutionPhase,
|
|
9
|
-
type TxValidationResult,
|
|
10
|
-
type TxValidator,
|
|
11
|
-
} from '@aztec/stdlib/tx';
|
|
12
|
-
|
|
13
|
-
export class PhasesTxValidator implements TxValidator<Tx> {
|
|
14
|
-
#log = createLogger('sequencer:tx_validator:tx_phases');
|
|
15
|
-
private contractsDB: PublicContractsDB;
|
|
16
|
-
|
|
17
|
-
constructor(contracts: ContractDataSource, private setupAllowList: AllowedElement[], private blockNumber: number) {
|
|
18
|
-
this.contractsDB = new PublicContractsDB(contracts);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async validateTx(tx: Tx): Promise<TxValidationResult> {
|
|
22
|
-
try {
|
|
23
|
-
// TODO(@spalladino): We add this just to handle public authwit-check calls during setup
|
|
24
|
-
// which are needed for public FPC flows, but fail if the account contract hasnt been deployed yet,
|
|
25
|
-
// which is what we're trying to do as part of the current txs.
|
|
26
|
-
await this.contractsDB.addNewContracts(tx);
|
|
27
|
-
|
|
28
|
-
if (!tx.data.forPublic) {
|
|
29
|
-
this.#log.debug(
|
|
30
|
-
`Tx ${await Tx.getHash(tx)} does not contain enqueued public functions. Skipping phases validation.`,
|
|
31
|
-
);
|
|
32
|
-
return { result: 'valid' };
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const setupFns = getCallRequestsWithCalldataByPhase(tx, TxExecutionPhase.SETUP);
|
|
36
|
-
for (const setupFn of setupFns) {
|
|
37
|
-
if (!(await this.isOnAllowList(setupFn, this.setupAllowList))) {
|
|
38
|
-
this.#log.warn(
|
|
39
|
-
`Rejecting tx ${await Tx.getHash(tx)} because it calls setup function not on allow list: ${
|
|
40
|
-
setupFn.request.contractAddress
|
|
41
|
-
}:${setupFn.functionSelector}`,
|
|
42
|
-
{ allowList: this.setupAllowList },
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
return { result: 'invalid', reason: ['Setup function not on allow list'] };
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return { result: 'valid' };
|
|
50
|
-
} finally {
|
|
51
|
-
this.contractsDB.clearContractsForTx();
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
private async isOnAllowList(
|
|
56
|
-
publicCall: PublicCallRequestWithCalldata,
|
|
57
|
-
allowList: AllowedElement[],
|
|
58
|
-
): Promise<boolean> {
|
|
59
|
-
if (publicCall.isEmpty()) {
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const contractAddress = publicCall.request.contractAddress;
|
|
64
|
-
const functionSelector = publicCall.functionSelector;
|
|
65
|
-
|
|
66
|
-
// do these checks first since they don't require the contract class
|
|
67
|
-
for (const entry of allowList) {
|
|
68
|
-
if ('address' in entry && !('selector' in entry)) {
|
|
69
|
-
if (contractAddress.equals(entry.address)) {
|
|
70
|
-
return true;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if ('address' in entry && 'selector' in entry) {
|
|
75
|
-
if (contractAddress.equals(entry.address) && entry.selector.equals(functionSelector)) {
|
|
76
|
-
return true;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const contractClass = await this.contractsDB.getContractInstance(contractAddress, this.blockNumber);
|
|
81
|
-
|
|
82
|
-
if (!contractClass) {
|
|
83
|
-
throw new Error(`Contract not found: ${contractAddress}`);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if ('classId' in entry && !('selector' in entry)) {
|
|
87
|
-
if (contractClass.currentContractClassId.equals(entry.classId)) {
|
|
88
|
-
return true;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if ('classId' in entry && 'selector' in entry) {
|
|
93
|
-
if (
|
|
94
|
-
contractClass.currentContractClassId.equals(entry.classId) &&
|
|
95
|
-
(entry.selector === undefined || entry.selector.equals(functionSelector))
|
|
96
|
-
) {
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { Fr } from '@aztec/foundation/fields';
|
|
2
|
-
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
3
|
-
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
|
-
import { HashedValues, type Tx } from '@aztec/stdlib/tx';
|
|
5
|
-
|
|
6
|
-
export function patchNonRevertibleFn(
|
|
7
|
-
tx: Tx,
|
|
8
|
-
index: number,
|
|
9
|
-
overrides: { address?: AztecAddress; selector: FunctionSelector; args?: Fr[]; msgSender?: AztecAddress },
|
|
10
|
-
): Promise<AztecAddress> {
|
|
11
|
-
return patchFn('nonRevertibleAccumulatedData', tx, index, overrides);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function patchRevertibleFn(
|
|
15
|
-
tx: Tx,
|
|
16
|
-
index: number,
|
|
17
|
-
overrides: { address?: AztecAddress; selector: FunctionSelector; args?: Fr[]; msgSender?: AztecAddress },
|
|
18
|
-
): Promise<AztecAddress> {
|
|
19
|
-
return patchFn('revertibleAccumulatedData', tx, index, overrides);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async function patchFn(
|
|
23
|
-
where: 'revertibleAccumulatedData' | 'nonRevertibleAccumulatedData',
|
|
24
|
-
tx: Tx,
|
|
25
|
-
index: number,
|
|
26
|
-
overrides: { address?: AztecAddress; selector: FunctionSelector; args?: Fr[]; msgSender?: AztecAddress },
|
|
27
|
-
): Promise<AztecAddress> {
|
|
28
|
-
const calldataIndex =
|
|
29
|
-
where === 'nonRevertibleAccumulatedData'
|
|
30
|
-
? index
|
|
31
|
-
: index + tx.data.forPublic!.nonRevertibleAccumulatedData.publicCallRequests.length;
|
|
32
|
-
const calldata = [overrides.selector.toField(), ...(overrides.args ?? [])];
|
|
33
|
-
const hashedCalldata = await HashedValues.fromCalldata(calldata);
|
|
34
|
-
tx.publicFunctionCalldata[calldataIndex] = hashedCalldata;
|
|
35
|
-
|
|
36
|
-
const request = tx.data.forPublic![where].publicCallRequests[index];
|
|
37
|
-
request.contractAddress = overrides.address ?? request.contractAddress;
|
|
38
|
-
request.msgSender = overrides.msgSender ?? request.msgSender;
|
|
39
|
-
request.calldataHash = hashedCalldata.hash;
|
|
40
|
-
tx.data.forPublic![where].publicCallRequests[index] = request;
|
|
41
|
-
|
|
42
|
-
return request.contractAddress;
|
|
43
|
-
}
|