Skip to content

Commit c9a4d88

Browse files
authored
chore: Remove default gas settings (#10163)
Deletes default fee in gas settings, and makes `maxFeePerGas` required for initializing a `GasSettings` instance. Built on top of #10105.
1 parent 9e19244 commit c9a4d88

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+246
-219
lines changed

l1-contracts/src/core/libraries/ConstantsGen.sol

+1-2
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,7 @@ library Constants {
9797
uint256 internal constant AZTEC_MAX_EPOCH_DURATION = 32;
9898
uint256 internal constant GENESIS_ARCHIVE_ROOT =
9999
1002640778211850180189505934749257244705296832326768971348723156503780793518;
100-
uint256 internal constant FEE_JUICE_INITIAL_MINT = 20000000000000000000;
101-
uint256 internal constant FEE_FUNDING_FOR_TESTER_ACCOUNT = 100000000000000000000;
100+
uint256 internal constant FEE_JUICE_INITIAL_MINT = 200000000000000000000;
102101
uint256 internal constant PUBLIC_DISPATCH_SELECTOR = 3578010381;
103102
uint256 internal constant MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS = 3000;
104103
uint256 internal constant MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS = 3000;

noir-projects/noir-protocol-circuits/crates/types/src/constants.nr

+1-2
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,7 @@ pub global GENESIS_ARCHIVE_ROOT: Field =
138138
0x0237797d6a2c04d20d4fa06b74482bd970ccd51a43d9b05b57e9b91fa1ae1cae;
139139
// The following and the value in `deploy_l1_contracts` must match. We should not have the code both places, but
140140
// we are running into circular dependency issues. #3342
141-
global FEE_JUICE_INITIAL_MINT: Field = 20000000000000000000;
142-
global FEE_FUNDING_FOR_TESTER_ACCOUNT: Field = 100000000000000000000; // 100e18
141+
global FEE_JUICE_INITIAL_MINT: Field = 200000000000000000000;
143142
// Last 4 bytes of the Poseidon2 hash of 'public_dispatch(Field)'.
144143
pub global PUBLIC_DISPATCH_SELECTOR: Field = 0xd5441b0d;
145144

yarn-project/accounts/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"version": "0.1.0",
66
"type": "module",
77
"exports": {
8+
"./dapp": "./dest/dapp/index.js",
89
"./defaults": "./dest/defaults/index.js",
910
"./ecdsa": "./dest/ecdsa/index.js",
1011
"./schnorr": "./dest/schnorr/index.js",
@@ -101,4 +102,4 @@
101102
"engines": {
102103
"node": ">=18"
103104
}
104-
}
105+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { type AccountWallet, type AuthWitnessProvider } from '@aztec/aztec.js';
2+
import { type AztecAddress, type CompleteAddress, type NodeInfo } from '@aztec/circuits.js';
3+
import { DefaultDappEntrypoint } from '@aztec/entrypoints/dapp';
4+
5+
import { DefaultAccountInterface } from '../defaults/account_interface.js';
6+
7+
/**
8+
* Default implementation for an account interface that uses a dapp entrypoint.
9+
*/
10+
export class DefaultDappInterface extends DefaultAccountInterface {
11+
constructor(
12+
authWitnessProvider: AuthWitnessProvider,
13+
userAddress: CompleteAddress,
14+
dappAddress: AztecAddress,
15+
nodeInfo: Pick<NodeInfo, 'l1ChainId' | 'protocolVersion'>,
16+
) {
17+
super(authWitnessProvider, userAddress, nodeInfo);
18+
this.entrypoint = new DefaultDappEntrypoint(
19+
userAddress.address,
20+
authWitnessProvider,
21+
dappAddress,
22+
nodeInfo.l1ChainId,
23+
nodeInfo.protocolVersion,
24+
);
25+
}
26+
27+
static createFromUserWallet(wallet: AccountWallet, dappAddress: AztecAddress): DefaultDappInterface {
28+
return new DefaultDappInterface(wallet, wallet.getCompleteAddress(), dappAddress, {
29+
l1ChainId: wallet.getChainId().toNumber(),
30+
protocolVersion: wallet.getVersion().toNumber(),
31+
});
32+
}
33+
}
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './dapp_interface.js';

yarn-project/accounts/src/defaults/account_interface.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import { DefaultAccountEntrypoint } from '@aztec/entrypoints/account';
99
* entrypoint signature, which accept an AppPayload and a FeePayload as defined in noir-libs/aztec-noir/src/entrypoint module
1010
*/
1111
export class DefaultAccountInterface implements AccountInterface {
12-
private entrypoint: EntrypointInterface;
12+
protected entrypoint: EntrypointInterface;
13+
1314
private chainId: Fr;
1415
private version: Fr;
1516

Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
import { type NoirCompiledContract, loadContractArtifact } from '@aztec/aztec.js';
1+
import { type ContractArtifact, type NoirCompiledContract, loadContractArtifact } from '@aztec/aztec.js';
22

33
import EcdsaKAccountContractJson from '../../../artifacts/EcdsaKAccount.json' assert { type: 'json' };
44

5-
export const EcdsaKAccountContractArtifact = loadContractArtifact(EcdsaKAccountContractJson as NoirCompiledContract);
5+
export const EcdsaKAccountContractArtifact: ContractArtifact = loadContractArtifact(
6+
EcdsaKAccountContractJson as NoirCompiledContract,
7+
);

yarn-project/aztec.js/src/account_manager/deploy_account_method.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,16 @@ export class DeployAccountMethod extends DeployMethod {
4646
: feePaymentNameOrArtifact;
4747
}
4848

49-
protected override async getInitializeFunctionCalls(options: DeployOptions): Promise<ExecutionRequestInit> {
49+
protected override async getInitializeFunctionCalls(
50+
options: DeployOptions,
51+
): Promise<Pick<ExecutionRequestInit, 'calls' | 'authWitnesses' | 'packedArguments'>> {
5052
const exec = await super.getInitializeFunctionCalls(options);
5153

5254
if (options.fee && this.#feePaymentArtifact) {
5355
const { address } = this.getInstance();
5456
const emptyAppPayload = EntrypointPayload.fromAppExecution([]);
55-
const feePayload = await EntrypointPayload.fromFeeOptions(address, options?.fee);
57+
const fee = await this.getDefaultFeeOptions(options.fee);
58+
const feePayload = await EntrypointPayload.fromFeeOptions(address, fee);
5659

5760
exec.calls.push({
5861
name: this.#feePaymentArtifact.name,

yarn-project/aztec.js/src/account_manager/index.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { DeployAccountSentTx } from './deploy_account_sent_tx.js';
1717
*/
1818
export type DeployAccountOptions = Pick<
1919
DeployOptions,
20-
'fee' | 'skipClassRegistration' | 'skipPublicDeployment' | 'estimateGas' | 'skipInitialization'
20+
'fee' | 'skipClassRegistration' | 'skipPublicDeployment' | 'skipInitialization'
2121
>;
2222

2323
/**
@@ -166,7 +166,6 @@ export class AccountManager {
166166
skipInitialization: opts?.skipInitialization ?? false,
167167
universalDeploy: true,
168168
fee: opts?.fee,
169-
estimateGas: opts?.estimateGas,
170169
}),
171170
)
172171
.then(tx => tx.getTxHash());

yarn-project/aztec.js/src/contract/base_contract_interaction.ts

+37-18
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import { type Fr, GasSettings } from '@aztec/circuits.js';
33
import { createDebugLogger } from '@aztec/foundation/log';
44

55
import { type Wallet } from '../account/wallet.js';
6-
import { type ExecutionRequestInit, type FeeOptions } from '../entrypoint/entrypoint.js';
6+
import { type ExecutionRequestInit } from '../entrypoint/entrypoint.js';
7+
import { type FeeOptions, type UserFeeOptions } from '../entrypoint/payload.js';
8+
import { NoFeePaymentMethod } from '../fee/no_fee_payment_method.js';
79
import { getGasLimits } from './get_gas_limits.js';
810
import { ProvenTx } from './proven_tx.js';
911
import { SentTx } from './sent_tx.js';
@@ -16,11 +18,7 @@ export type SendMethodOptions = {
1618
/** Wether to skip the simulation of the public part of the transaction. */
1719
skipPublicSimulation?: boolean;
1820
/** The fee options for the transaction. */
19-
fee?: FeeOptions;
20-
/** Whether to run an initial simulation of the tx with high gas limit to figure out actual gas settings (will default to true later down the road). */
21-
estimateGas?: boolean;
22-
/** Percentage to pad the suggested gas limits by, if empty, defaults to 10%. */
23-
estimatedGasPad?: number;
21+
fee?: UserFeeOptions;
2422
/** Custom nonce to inject into the app payload of the transaction. Useful when trying to cancel an ongoing transaction by creating a new one with a higher fee */
2523
nonce?: Fr;
2624
/** Whether the transaction can be cancelled. If true, an extra nullifier will be emitted: H(nonce, GENERATOR_INDEX__TX_NULLIFIER) */
@@ -92,33 +90,54 @@ export abstract class BaseContractInteraction {
9290
public async estimateGas(
9391
opts?: Omit<SendMethodOptions, 'estimateGas' | 'skipPublicSimulation'>,
9492
): Promise<Pick<GasSettings, 'gasLimits' | 'teardownGasLimits'>> {
95-
const txRequest = await this.create({ ...opts, estimateGas: false });
93+
const txRequest = await this.create({ ...opts, fee: { ...opts?.fee, estimateGas: false } });
9694
const simulationResult = await this.wallet.simulateTx(txRequest, true);
9795
const { totalGas: gasLimits, teardownGas: teardownGasLimits } = getGasLimits(
9896
simulationResult,
99-
opts?.estimatedGasPad,
97+
opts?.fee?.estimatedGasPadding,
10098
);
10199
return { gasLimits, teardownGasLimits };
102100
}
103101

104102
/**
105-
* Helper method to return fee options based on the user opts, estimating tx gas if needed.
103+
* Returns default fee options based on the user opts without running a simulation for gas estimation.
104+
* @param fee - User-provided fee options.
105+
*/
106+
protected async getDefaultFeeOptions(fee: UserFeeOptions | undefined): Promise<FeeOptions> {
107+
const maxFeesPerGas = fee?.gasSettings?.maxFeesPerGas ?? (await this.wallet.getCurrentBaseFees());
108+
const paymentMethod = fee?.paymentMethod ?? new NoFeePaymentMethod();
109+
const gasSettings: GasSettings = GasSettings.default({ ...fee?.gasSettings, maxFeesPerGas });
110+
return { gasSettings, paymentMethod };
111+
}
112+
113+
/**
114+
* Return fee options based on the user opts, estimating tx gas if needed.
106115
* @param request - Request to execute for this interaction.
107116
* @param pad - Percentage to pad the suggested gas limits by, as decimal (e.g., 0.10 for 10%).
108117
* @returns Fee options for the actual transaction.
109118
*/
110-
protected async getFeeOptionsFromEstimatedGas(request: ExecutionRequestInit, pad?: number) {
111-
const fee = request.fee;
112-
if (fee) {
113-
const txRequest = await this.wallet.createTxExecutionRequest(request);
119+
protected async getFeeOptions(
120+
request: Omit<ExecutionRequestInit, 'fee'> & { /** User-provided fee options */ fee?: UserFeeOptions },
121+
): Promise<FeeOptions> {
122+
const defaultFeeOptions = await this.getDefaultFeeOptions(request.fee);
123+
const paymentMethod = defaultFeeOptions.paymentMethod;
124+
const maxFeesPerGas = defaultFeeOptions.gasSettings.maxFeesPerGas;
125+
126+
let gasSettings = defaultFeeOptions.gasSettings;
127+
if (request.fee?.estimateGas) {
128+
const feeForEstimation: FeeOptions = { paymentMethod, gasSettings };
129+
const txRequest = await this.wallet.createTxExecutionRequest({ ...request, fee: feeForEstimation });
114130
const simulationResult = await this.wallet.simulateTx(txRequest, true);
115-
const { totalGas: gasLimits, teardownGas: teardownGasLimits } = getGasLimits(simulationResult, pad);
116-
this.log.debug(
131+
const { totalGas: gasLimits, teardownGas: teardownGasLimits } = getGasLimits(
132+
simulationResult,
133+
request.fee?.estimatedGasPadding,
134+
);
135+
gasSettings = GasSettings.from({ maxFeesPerGas, gasLimits, teardownGasLimits });
136+
this.log.verbose(
117137
`Estimated gas limits for tx: DA=${gasLimits.daGas} L2=${gasLimits.l2Gas} teardownDA=${teardownGasLimits.daGas} teardownL2=${teardownGasLimits.l2Gas}`,
118138
);
119-
const gasSettings = GasSettings.default({ ...fee.gasSettings, gasLimits, teardownGasLimits });
120-
return { ...fee, gasSettings };
121139
}
122-
return fee;
140+
141+
return { gasSettings, paymentMethod };
123142
}
124143
}

yarn-project/aztec.js/src/contract/batch_call.ts

+18-29
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ export class BatchCall extends BaseContractInteraction {
1919
*/
2020
public async create(opts?: SendMethodOptions): Promise<TxExecutionRequest> {
2121
const calls = this.calls;
22-
const fee = opts?.estimateGas
23-
? await this.getFeeOptionsFromEstimatedGas({ calls, fee: opts?.fee }, opts?.estimatedGasPad)
24-
: opts?.fee;
25-
return await this.wallet.createTxExecutionRequest({ calls, fee });
22+
const fee = await this.getFeeOptions({ calls, ...opts });
23+
return await this.wallet.createTxExecutionRequest({ calls, ...opts, fee });
2624
}
2725

2826
/**
@@ -35,48 +33,39 @@ export class BatchCall extends BaseContractInteraction {
3533
* @returns The result of the transaction as returned by the contract function.
3634
*/
3735
public async simulate(options: SimulateMethodOptions = {}): Promise<any> {
38-
const { calls, unconstrained } = this.calls.reduce<{
39-
/**
40-
* Keep track of the number of private calls to retrieve the return values
41-
*/
36+
const { indexedCalls, unconstrained } = this.calls.reduce<{
37+
/** Keep track of the number of private calls to retrieve the return values */
4238
privateIndex: 0;
43-
/**
44-
* Keep track of the number of private calls to retrieve the return values
45-
*/
39+
/** Keep track of the number of public calls to retrieve the return values */
4640
publicIndex: 0;
47-
/**
48-
* The public and private function calls in the batch
49-
*/
50-
calls: [FunctionCall, number, number][];
51-
/**
52-
* The unconstrained function calls in the batch.
53-
*/
41+
/** The public and private function calls in the batch */
42+
indexedCalls: [FunctionCall, number, number][];
43+
/** The unconstrained function calls in the batch. */
5444
unconstrained: [FunctionCall, number][];
5545
}>(
5646
(acc, current, index) => {
5747
if (current.type === FunctionType.UNCONSTRAINED) {
5848
acc.unconstrained.push([current, index]);
5949
} else {
60-
acc.calls.push([
50+
acc.indexedCalls.push([
6151
current,
6252
index,
6353
current.type === FunctionType.PRIVATE ? acc.privateIndex++ : acc.publicIndex++,
6454
]);
6555
}
6656
return acc;
6757
},
68-
{ calls: [], unconstrained: [], publicIndex: 0, privateIndex: 0 },
58+
{ indexedCalls: [], unconstrained: [], publicIndex: 0, privateIndex: 0 },
6959
);
7060

71-
const txRequest = await this.wallet.createTxExecutionRequest({ calls: calls.map(indexedCall => indexedCall[0]) });
61+
const calls = indexedCalls.map(([call]) => call);
62+
const fee = await this.getFeeOptions({ calls, ...options });
63+
const txRequest = await this.wallet.createTxExecutionRequest({ calls, ...options, fee });
7264

73-
const unconstrainedCalls = unconstrained.map(async indexedCall => {
74-
const call = indexedCall[0];
75-
return [
76-
await this.wallet.simulateUnconstrained(call.name, call.args, call.to, options?.from),
77-
indexedCall[1],
78-
] as const;
79-
});
65+
const unconstrainedCalls = unconstrained.map(
66+
async ([call, index]) =>
67+
[await this.wallet.simulateUnconstrained(call.name, call.args, call.to, options?.from), index] as const,
68+
);
8069

8170
const [unconstrainedResults, simulatedTx] = await Promise.all([
8271
Promise.all(unconstrainedCalls),
@@ -88,7 +77,7 @@ export class BatchCall extends BaseContractInteraction {
8877
unconstrainedResults.forEach(([result, index]) => {
8978
results[index] = result;
9079
});
91-
calls.forEach(([call, callIndex, resultIndex]) => {
80+
indexedCalls.forEach(([call, callIndex, resultIndex]) => {
9281
// As account entrypoints are private, for private functions we retrieve the return values from the first nested call
9382
// since we're interested in the first set of values AFTER the account entrypoint
9483
// For public functions we retrieve the first values directly from the public output.

yarn-project/aztec.js/src/contract/contract.test.ts

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
CompleteAddress,
1212
type ContractInstanceWithAddress,
1313
EthAddress,
14+
GasFees,
1415
type NodeInfo,
1516
} from '@aztec/circuits.js';
1617
import { type L1ContractAddresses } from '@aztec/ethereum';
@@ -153,6 +154,7 @@ describe('Contract Class', () => {
153154
wallet.getNodeInfo.mockResolvedValue(mockNodeInfo);
154155
wallet.proveTx.mockResolvedValue(mockTxProvingResult);
155156
wallet.getRegisteredAccounts.mockResolvedValue([account]);
157+
wallet.getCurrentBaseFees.mockResolvedValue(new GasFees(100, 100));
156158
});
157159

158160
it('should create and send a contract method tx', async () => {

yarn-project/aztec.js/src/contract/contract_function_interaction.ts

+4-11
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,14 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
5858
* @param opts - An optional object containing additional configuration for the transaction.
5959
* @returns A Promise that resolves to a transaction instance.
6060
*/
61-
public async create(opts?: SendMethodOptions): Promise<TxExecutionRequest> {
61+
public async create(opts: SendMethodOptions = {}): Promise<TxExecutionRequest> {
6262
if (this.functionDao.functionType === FunctionType.UNCONSTRAINED) {
6363
throw new Error("Can't call `create` on an unconstrained function.");
6464
}
6565
const calls = [this.request()];
66-
const fee = opts?.estimateGas
67-
? await this.getFeeOptionsFromEstimatedGas({ calls, fee: opts?.fee }, opts?.estimatedGasPad)
68-
: opts?.fee;
69-
const txRequest = await this.wallet.createTxExecutionRequest({
70-
calls,
71-
fee,
72-
nonce: opts?.nonce,
73-
cancellable: opts?.cancellable,
74-
});
75-
return txRequest;
66+
const fee = await this.getFeeOptions({ calls, ...opts });
67+
const { nonce, cancellable } = opts;
68+
return await this.wallet.createTxExecutionRequest({ calls, fee, nonce, cancellable });
7669
}
7770

7871
/**

0 commit comments

Comments
 (0)