@aztec/cli-wallet 0.86.0-starknet.1 → 0.87.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/bin/index.js +1 -1
- package/dest/cmds/create_account.d.ts +1 -1
- package/dest/cmds/create_account.d.ts.map +1 -1
- package/dest/cmds/create_account.js +25 -15
- package/dest/cmds/deploy.d.ts +1 -1
- package/dest/cmds/deploy.d.ts.map +1 -1
- package/dest/cmds/deploy.js +7 -2
- package/dest/cmds/deploy_account.d.ts +1 -1
- package/dest/cmds/deploy_account.d.ts.map +1 -1
- package/dest/cmds/deploy_account.js +25 -16
- package/dest/cmds/index.d.ts.map +1 -1
- package/dest/cmds/index.js +17 -16
- package/dest/cmds/profile.d.ts.map +1 -1
- package/dest/cmds/profile.js +2 -22
- package/dest/cmds/register_contract.d.ts +1 -1
- package/dest/cmds/register_contract.d.ts.map +1 -1
- package/dest/cmds/send.d.ts +1 -1
- package/dest/cmds/send.d.ts.map +1 -1
- package/dest/cmds/send.js +7 -2
- package/dest/cmds/simulate.d.ts +2 -1
- package/dest/cmds/simulate.d.ts.map +1 -1
- package/dest/cmds/simulate.js +10 -4
- package/dest/storage/wallet_db.d.ts +1 -3
- package/dest/storage/wallet_db.d.ts.map +1 -1
- package/dest/storage/wallet_db.js +1 -1
- package/dest/utils/accounts.d.ts +1 -1
- package/dest/utils/accounts.d.ts.map +1 -1
- package/dest/utils/ecdsa.d.ts +0 -2
- package/dest/utils/ecdsa.d.ts.map +1 -1
- package/dest/utils/options/fees.d.ts.map +1 -1
- package/dest/utils/options/options.d.ts +1 -0
- package/dest/utils/options/options.d.ts.map +1 -1
- package/dest/utils/options/options.js +6 -3
- package/dest/utils/profiling.d.ts +5 -0
- package/dest/utils/profiling.d.ts.map +1 -0
- package/dest/utils/profiling.js +32 -0
- package/package.json +15 -15
- package/src/bin/index.ts +1 -1
- package/src/cmds/create_account.ts +24 -14
- package/src/cmds/deploy.ts +8 -1
- package/src/cmds/deploy_account.ts +24 -15
- package/src/cmds/index.ts +51 -26
- package/src/cmds/profile.ts +3 -60
- package/src/cmds/register_contract.ts +1 -1
- package/src/cmds/send.ts +8 -1
- package/src/cmds/simulate.ts +14 -2
- package/src/storage/wallet_db.ts +1 -1
- package/src/utils/accounts.ts +1 -1
- package/src/utils/options/fees.ts +24 -15
- package/src/utils/options/options.ts +10 -3
- package/src/utils/profiling.ts +87 -0
|
@@ -18,7 +18,7 @@ export function integerArgParser(value, argName, min = Number.MIN_SAFE_INTEGER,
|
|
|
18
18
|
export function aliasedTxHashParser(txHash, db) {
|
|
19
19
|
try {
|
|
20
20
|
return parseTxHash(txHash);
|
|
21
|
-
} catch
|
|
21
|
+
} catch {
|
|
22
22
|
const prefixed = txHash.includes(':') ? txHash : `transactions:${txHash}`;
|
|
23
23
|
const rawTxHash = db ? db.tryRetrieveAlias(prefixed) : txHash;
|
|
24
24
|
return parseTxHash(rawTxHash);
|
|
@@ -28,7 +28,7 @@ export function aliasedAuthWitParser(witnesses, db) {
|
|
|
28
28
|
const parsedWitnesses = witnesses.split(',').map((witness)=>{
|
|
29
29
|
try {
|
|
30
30
|
return AuthWitness.fromString(witness);
|
|
31
|
-
} catch
|
|
31
|
+
} catch {
|
|
32
32
|
const prefixed = witness.includes(':') ? witness : `authwits:${witness}`;
|
|
33
33
|
const rawAuthWitness = db ? db.tryRetrieveAlias(prefixed) : witness;
|
|
34
34
|
return AuthWitness.fromString(rawAuthWitness);
|
|
@@ -79,6 +79,9 @@ export function createContractAddressOption(db) {
|
|
|
79
79
|
export function createDebugExecutionStepsDirOption() {
|
|
80
80
|
return new Option('--debug-execution-steps-dir <address>', 'Directory to write execution step artifacts for bb profiling/debugging.').makeOptionMandatory(false);
|
|
81
81
|
}
|
|
82
|
+
export function createVerboseOption() {
|
|
83
|
+
return new Option('-v, --verbose', 'Provide timings on all executed operations (synching, simulating, proving)').default(false);
|
|
84
|
+
}
|
|
82
85
|
export function artifactPathParser(filePath, db) {
|
|
83
86
|
if (filePath.includes('@')) {
|
|
84
87
|
const [pkg, contractName] = filePath.split('@');
|
|
@@ -108,7 +111,7 @@ async function contractArtifactFromWorkspace(pkg, contractName) {
|
|
|
108
111
|
const cwd = process.cwd();
|
|
109
112
|
try {
|
|
110
113
|
await stat(`${cwd}/Nargo.toml`);
|
|
111
|
-
} catch
|
|
114
|
+
} catch {
|
|
112
115
|
throw new Error('Invalid contract artifact argument provided. To use this option, command should be called from a nargo workspace');
|
|
113
116
|
}
|
|
114
117
|
const filesInTarget = await readdir(`${cwd}/${TARGET_DIR}`);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { LogFn } from '@aztec/foundation/log';
|
|
2
|
+
import type { PrivateExecutionStep } from '@aztec/stdlib/kernel';
|
|
3
|
+
import type { ProvingTimings, SimulationTimings } from '@aztec/stdlib/tx';
|
|
4
|
+
export declare function printProfileResult(timings: ProvingTimings | SimulationTimings, log: LogFn, executionSteps?: PrivateExecutionStep[]): void;
|
|
5
|
+
//# sourceMappingURL=profiling.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiling.d.ts","sourceRoot":"","sources":["../../src/utils/profiling.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAI1E,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,cAAc,GAAG,iBAAiB,EAC3C,GAAG,EAAE,KAAK,EACV,cAAc,CAAC,EAAE,oBAAoB,EAAE,QA6ExC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { format } from 'util';
|
|
2
|
+
export function printProfileResult(timings, log, executionSteps) {
|
|
3
|
+
log(format('\nPer circuit breakdown:\n'));
|
|
4
|
+
log(format(' ', 'Function name'.padEnd(50), 'Time'.padStart(13).padEnd(15), executionSteps ? 'Gates'.padStart(13).padEnd(15) : '', executionSteps ? 'Subtotal'.padStart(13).padEnd(15) : ''));
|
|
5
|
+
log(format(''.padEnd(50 + 15 + 15 + (executionSteps ? 15 + 15 : 0), '-')));
|
|
6
|
+
let acc = 0;
|
|
7
|
+
let biggest = executionSteps?.[0];
|
|
8
|
+
timings.perFunction.forEach((fn, i)=>{
|
|
9
|
+
const currentExecutionStep = executionSteps?.[i];
|
|
10
|
+
if (currentExecutionStep && biggest && currentExecutionStep.gateCount > biggest.gateCount) {
|
|
11
|
+
biggest = currentExecutionStep;
|
|
12
|
+
}
|
|
13
|
+
acc += currentExecutionStep ? currentExecutionStep.gateCount : 0;
|
|
14
|
+
log(format(' ', fn.functionName.padEnd(50), `${fn.time.toFixed(2)}ms`.padStart(13).padEnd(15), currentExecutionStep ? currentExecutionStep.gateCount.toLocaleString().padStart(13).padEnd(15) : '', currentExecutionStep ? acc.toLocaleString().padStart(15) : ''));
|
|
15
|
+
});
|
|
16
|
+
if (biggest) {
|
|
17
|
+
log(format('\nTotal gates:', acc.toLocaleString(), `(Biggest circuit: ${biggest.functionName} -> ${biggest.gateCount.toLocaleString()})`));
|
|
18
|
+
}
|
|
19
|
+
log(format('\nSync time:'.padEnd(25), `${timings.sync?.toFixed(2)}ms`.padStart(16)));
|
|
20
|
+
log(format('Private simulation time:'.padEnd(25), `${timings.perFunction.reduce((acc, { time })=>acc + time, 0).toFixed(2)}ms`.padStart(15)));
|
|
21
|
+
if (timings.proving) {
|
|
22
|
+
log(format('Proving time:'.padEnd(25), `${timings.proving?.toFixed(2)}ms`.padStart(15)));
|
|
23
|
+
}
|
|
24
|
+
if (timings.publicSimulation) {
|
|
25
|
+
log(format('Public simulation time:'.padEnd(25), `${timings.publicSimulation?.toFixed(2)}ms`.padStart(15)));
|
|
26
|
+
}
|
|
27
|
+
if (timings.validation) {
|
|
28
|
+
log(format('Validation time:'.padEnd(25), `${timings.validation?.toFixed(2)}ms`.padStart(15)));
|
|
29
|
+
}
|
|
30
|
+
log(format('Total time:'.padEnd(25), `${timings.total.toFixed(2)}ms`.padStart(15), `(${timings.unaccounted.toFixed(2)}ms unaccounted)`));
|
|
31
|
+
log('\n');
|
|
32
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/cli-wallet",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.87.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/cmds/index.js",
|
|
@@ -63,17 +63,17 @@
|
|
|
63
63
|
]
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@aztec/accounts": "0.
|
|
67
|
-
"@aztec/aztec.js": "0.
|
|
68
|
-
"@aztec/cli": "0.
|
|
69
|
-
"@aztec/entrypoints": "0.
|
|
70
|
-
"@aztec/ethereum": "0.
|
|
71
|
-
"@aztec/foundation": "0.
|
|
72
|
-
"@aztec/kv-store": "0.
|
|
73
|
-
"@aztec/noir-contracts.js": "0.
|
|
74
|
-
"@aztec/noir-noirc_abi": "0.
|
|
75
|
-
"@aztec/pxe": "0.
|
|
76
|
-
"@aztec/stdlib": "0.
|
|
66
|
+
"@aztec/accounts": "0.87.0",
|
|
67
|
+
"@aztec/aztec.js": "0.87.0",
|
|
68
|
+
"@aztec/cli": "0.87.0",
|
|
69
|
+
"@aztec/entrypoints": "0.87.0",
|
|
70
|
+
"@aztec/ethereum": "0.87.0",
|
|
71
|
+
"@aztec/foundation": "0.87.0",
|
|
72
|
+
"@aztec/kv-store": "0.87.0",
|
|
73
|
+
"@aztec/noir-contracts.js": "0.87.0",
|
|
74
|
+
"@aztec/noir-noirc_abi": "0.87.0",
|
|
75
|
+
"@aztec/pxe": "0.87.0",
|
|
76
|
+
"@aztec/stdlib": "0.87.0",
|
|
77
77
|
"commander": "^12.1.0",
|
|
78
78
|
"inquirer": "^10.1.8",
|
|
79
79
|
"source-map-support": "^0.5.21",
|
|
@@ -82,13 +82,13 @@
|
|
|
82
82
|
"devDependencies": {
|
|
83
83
|
"@jest/globals": "^29.5.0",
|
|
84
84
|
"@types/jest": "^29.5.0",
|
|
85
|
-
"@types/node": "^
|
|
85
|
+
"@types/node": "^22.15.17",
|
|
86
86
|
"@types/source-map-support": "^0.5.10",
|
|
87
87
|
"jest": "^29.5.0",
|
|
88
88
|
"jest-mock-extended": "^3.0.5",
|
|
89
89
|
"ts-jest": "^29.1.0",
|
|
90
90
|
"ts-node": "^10.9.1",
|
|
91
|
-
"typescript": "^5.
|
|
91
|
+
"typescript": "^5.3.3"
|
|
92
92
|
},
|
|
93
93
|
"files": [
|
|
94
94
|
"dest",
|
|
@@ -97,6 +97,6 @@
|
|
|
97
97
|
],
|
|
98
98
|
"types": "./dest/index.d.ts",
|
|
99
99
|
"engines": {
|
|
100
|
-
"node": ">=
|
|
100
|
+
"node": ">=20.10"
|
|
101
101
|
}
|
|
102
102
|
}
|
package/src/bin/index.ts
CHANGED
|
@@ -55,7 +55,7 @@ function injectInternalCommands(program: Command, log: LogFn, db: WalletDB) {
|
|
|
55
55
|
const options = command.optsWithGlobals();
|
|
56
56
|
const { alias } = options;
|
|
57
57
|
const value = Fr.random();
|
|
58
|
-
const hash = computeSecretHash(value);
|
|
58
|
+
const hash = await computeSecretHash(value);
|
|
59
59
|
|
|
60
60
|
await db.storeAlias('secrets', alias, Buffer.from(value.toString()), log);
|
|
61
61
|
await db.storeAlias('secrets', `${alias}:hash`, Buffer.from(hash.toString()), log);
|
|
@@ -5,6 +5,7 @@ import type { LogFn, Logger } from '@aztec/foundation/log';
|
|
|
5
5
|
|
|
6
6
|
import { type AccountType, createOrRetrieveAccount } from '../utils/accounts.js';
|
|
7
7
|
import { type IFeeOpts, printGasEstimates } from '../utils/options/fees.js';
|
|
8
|
+
import { printProfileResult } from '../utils/profiling.js';
|
|
8
9
|
|
|
9
10
|
export async function createAccount(
|
|
10
11
|
client: PXE,
|
|
@@ -18,6 +19,7 @@ export async function createAccount(
|
|
|
18
19
|
wait: boolean,
|
|
19
20
|
feeOpts: IFeeOpts,
|
|
20
21
|
json: boolean,
|
|
22
|
+
verbose: boolean,
|
|
21
23
|
debugLogger: Logger,
|
|
22
24
|
log: LogFn,
|
|
23
25
|
) {
|
|
@@ -71,20 +73,23 @@ export async function createAccount(
|
|
|
71
73
|
skipInitialization: skipInitialization,
|
|
72
74
|
...(await feeOpts.toDeployAccountOpts(wallet)),
|
|
73
75
|
};
|
|
76
|
+
/*
|
|
77
|
+
* This is usually handled by accountManager.deploy(), but we're accessing the lower
|
|
78
|
+
* level method to get gas and timings. That means we have to replicate some of the logic here.
|
|
79
|
+
* In case we're deploying our own account, we need to hijack the payment method for the fee,
|
|
80
|
+
* wrapping it in the one that will make use of the freshly deployed account's
|
|
81
|
+
* entrypoint. For reference, see aztec.js/src/account_manager.ts:deploy()
|
|
82
|
+
* Also, salt and universalDeploy have to be explicitly provided
|
|
83
|
+
*/
|
|
84
|
+
deployOpts.fee =
|
|
85
|
+
!deployOpts?.deployWallet && deployOpts?.fee
|
|
86
|
+
? { ...deployOpts.fee, paymentMethod: await account.getSelfPaymentMethod(deployOpts.fee.paymentMethod) }
|
|
87
|
+
: deployOpts?.fee;
|
|
88
|
+
|
|
89
|
+
const deployMethod = await account.getDeployMethod(deployOpts.deployWallet);
|
|
90
|
+
|
|
74
91
|
if (feeOpts.estimateOnly) {
|
|
75
|
-
|
|
76
|
-
* This is usually handled by accountManager.deploy(), but we're accessing the lower
|
|
77
|
-
* level method to get the gas estimates. That means we have to replicate some of the logic here.
|
|
78
|
-
* In case we're deploying our own account, we need to hijack the payment method for the fee,
|
|
79
|
-
* wrapping it in the one that will make use of the freshly deployed account's
|
|
80
|
-
* entrypoint. For reference, see aztec.js/src/account_manager.ts:deploy()
|
|
81
|
-
*/
|
|
82
|
-
const fee =
|
|
83
|
-
!deployOpts?.deployWallet && deployOpts?.fee
|
|
84
|
-
? { ...deployOpts.fee, paymentMethod: await account.getSelfPaymentMethod(deployOpts.fee.paymentMethod) }
|
|
85
|
-
: deployOpts?.fee;
|
|
86
|
-
const deployMethod = await account.getDeployMethod(deployOpts.deployWallet);
|
|
87
|
-
const gas = await deployMethod.estimateGas({ ...deployOpts, fee, universalDeploy: true });
|
|
92
|
+
const gas = await deployMethod.estimateGas({ ...deployOpts, universalDeploy: true, contractAddressSalt: salt });
|
|
88
93
|
if (json) {
|
|
89
94
|
out.fee = {
|
|
90
95
|
gasLimits: {
|
|
@@ -100,7 +105,12 @@ export async function createAccount(
|
|
|
100
105
|
printGasEstimates(feeOpts, gas, log);
|
|
101
106
|
}
|
|
102
107
|
} else {
|
|
103
|
-
|
|
108
|
+
const provenTx = await deployMethod.prove({ ...deployOpts, universalDeploy: true, contractAddressSalt: salt });
|
|
109
|
+
if (verbose) {
|
|
110
|
+
printProfileResult(provenTx.timings!, log);
|
|
111
|
+
}
|
|
112
|
+
tx = provenTx.send();
|
|
113
|
+
|
|
104
114
|
const txHash = await tx.getTxHash();
|
|
105
115
|
debugLogger.debug(`Account contract tx sent with hash ${txHash}`);
|
|
106
116
|
out.txHash = txHash;
|
package/src/cmds/deploy.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { getAllFunctionAbis, getInitializer } from '@aztec/stdlib/abi';
|
|
|
5
5
|
import { PublicKeys } from '@aztec/stdlib/keys';
|
|
6
6
|
|
|
7
7
|
import { type IFeeOpts, printGasEstimates } from '../utils/options/fees.js';
|
|
8
|
+
import { printProfileResult } from '../utils/profiling.js';
|
|
8
9
|
|
|
9
10
|
export async function deploy(
|
|
10
11
|
wallet: AccountWalletWithSecretKey,
|
|
@@ -20,6 +21,7 @@ export async function deploy(
|
|
|
20
21
|
universalDeploy: boolean | undefined,
|
|
21
22
|
wait: boolean,
|
|
22
23
|
feeOpts: IFeeOpts,
|
|
24
|
+
verbose: boolean,
|
|
23
25
|
debugLogger: Logger,
|
|
24
26
|
log: LogFn,
|
|
25
27
|
logJson: (output: any) => void,
|
|
@@ -59,7 +61,12 @@ export async function deploy(
|
|
|
59
61
|
return;
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
const
|
|
64
|
+
const provenTx = await deploy.prove(deployOpts);
|
|
65
|
+
if (verbose) {
|
|
66
|
+
printProfileResult(provenTx.timings!, log);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const tx = provenTx.send();
|
|
63
70
|
|
|
64
71
|
const txHash = await tx.getTxHash();
|
|
65
72
|
debugLogger.debug(`Deploy tx sent with hash ${txHash}`);
|
|
@@ -3,6 +3,7 @@ import { prettyPrintJSON } from '@aztec/cli/cli-utils';
|
|
|
3
3
|
import type { LogFn, Logger } from '@aztec/foundation/log';
|
|
4
4
|
|
|
5
5
|
import { type IFeeOpts, printGasEstimates } from '../utils/options/fees.js';
|
|
6
|
+
import { printProfileResult } from '../utils/profiling.js';
|
|
6
7
|
|
|
7
8
|
export async function deployAccount(
|
|
8
9
|
account: AccountManager,
|
|
@@ -11,6 +12,7 @@ export async function deployAccount(
|
|
|
11
12
|
publicDeploy: boolean,
|
|
12
13
|
feeOpts: IFeeOpts,
|
|
13
14
|
json: boolean,
|
|
15
|
+
verbose: boolean,
|
|
14
16
|
debugLogger: Logger,
|
|
15
17
|
log: LogFn,
|
|
16
18
|
) {
|
|
@@ -43,26 +45,28 @@ export async function deployAccount(
|
|
|
43
45
|
let txReceipt;
|
|
44
46
|
|
|
45
47
|
const deployOpts: DeployAccountOptions = {
|
|
46
|
-
skipInitialization: false,
|
|
47
48
|
skipPublicDeployment: !publicDeploy,
|
|
48
49
|
skipClassRegistration: !registerClass,
|
|
49
50
|
...(await feeOpts.toDeployAccountOpts(wallet)),
|
|
50
51
|
};
|
|
51
52
|
|
|
53
|
+
/*
|
|
54
|
+
* This is usually handled by accountManager.deploy(), but we're accessing the lower
|
|
55
|
+
* level method to get gas and timings. That means we have to replicate some of the logic here.
|
|
56
|
+
* In case we're deploying our own account, we need to hijack the payment method for the fee,
|
|
57
|
+
* wrapping it in the one that will make use of the freshly deployed account's
|
|
58
|
+
* entrypoint. For reference, see aztec.js/src/account_manager.ts:deploy()
|
|
59
|
+
* Also, salt and universalDeploy have to be explicitly provided
|
|
60
|
+
*/
|
|
61
|
+
deployOpts.fee =
|
|
62
|
+
!deployOpts?.deployWallet && deployOpts?.fee
|
|
63
|
+
? { ...deployOpts.fee, paymentMethod: await account.getSelfPaymentMethod(deployOpts.fee.paymentMethod) }
|
|
64
|
+
: deployOpts?.fee;
|
|
65
|
+
|
|
66
|
+
const deployMethod = await account.getDeployMethod(deployOpts.deployWallet);
|
|
67
|
+
|
|
52
68
|
if (feeOpts.estimateOnly) {
|
|
53
|
-
|
|
54
|
-
* This is usually handled by accountManager.deploy(), but we're accessing the lower
|
|
55
|
-
* level method to get the gas estimates. That means we have to replicate some of the logic here.
|
|
56
|
-
* In case we're deploying our own account, we need to hijack the payment method for the fee,
|
|
57
|
-
* wrapping it in the one that will make use of the freshly deployed account's
|
|
58
|
-
* entrypoint. For reference, see aztec.js/src/account_manager.ts:deploy()
|
|
59
|
-
*/
|
|
60
|
-
const fee =
|
|
61
|
-
!deployOpts?.deployWallet && deployOpts?.fee
|
|
62
|
-
? { ...deployOpts.fee, paymentMethod: await account.getSelfPaymentMethod(deployOpts.fee.paymentMethod) }
|
|
63
|
-
: deployOpts?.fee;
|
|
64
|
-
const deployMethod = await account.getDeployMethod(deployOpts.deployWallet);
|
|
65
|
-
const gas = await deployMethod.estimateGas({ ...deployOpts, fee, universalDeploy: true });
|
|
69
|
+
const gas = await deployMethod.estimateGas({ ...deployOpts, universalDeploy: true, contractAddressSalt: salt });
|
|
66
70
|
if (json) {
|
|
67
71
|
out.fee = {
|
|
68
72
|
gasLimits: {
|
|
@@ -78,7 +82,12 @@ export async function deployAccount(
|
|
|
78
82
|
printGasEstimates(feeOpts, gas, log);
|
|
79
83
|
}
|
|
80
84
|
} else {
|
|
81
|
-
|
|
85
|
+
const provenTx = await deployMethod.prove({ ...deployOpts, universalDeploy: true, contractAddressSalt: salt });
|
|
86
|
+
if (verbose) {
|
|
87
|
+
printProfileResult(provenTx.timings!, log);
|
|
88
|
+
}
|
|
89
|
+
tx = provenTx.send();
|
|
90
|
+
|
|
82
91
|
const txHash = await tx.getTxHash();
|
|
83
92
|
debugLogger.debug(`Account contract tx sent with hash ${txHash}`);
|
|
84
93
|
out.txHash = txHash;
|
package/src/cmds/index.ts
CHANGED
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
createContractAddressOption,
|
|
40
40
|
createDebugExecutionStepsDirOption,
|
|
41
41
|
createTypeOption,
|
|
42
|
+
createVerboseOption,
|
|
42
43
|
integerArgParser,
|
|
43
44
|
parseGasFees,
|
|
44
45
|
parsePaymentMethod,
|
|
@@ -99,12 +100,14 @@ export function injectCommands(
|
|
|
99
100
|
.option('--json', 'Emit output as json')
|
|
100
101
|
// `options.wait` is default true. Passing `--no-wait` will set it to false.
|
|
101
102
|
// https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
|
|
102
|
-
.option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction')
|
|
103
|
+
.option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction')
|
|
104
|
+
.addOption(createVerboseOption());
|
|
103
105
|
|
|
104
106
|
addOptions(createAccountCommand, FeeOptsWithFeePayer.getOptions()).action(async (_options, command) => {
|
|
105
107
|
const { createAccount } = await import('./create_account.js');
|
|
106
108
|
const options = command.optsWithGlobals();
|
|
107
|
-
const { type, secretKey, wait, registerOnly, skipInitialization, publicDeploy, rpcUrl, alias, json } =
|
|
109
|
+
const { type, secretKey, wait, registerOnly, skipInitialization, publicDeploy, rpcUrl, alias, json, verbose } =
|
|
110
|
+
options;
|
|
108
111
|
let { publicKey } = options;
|
|
109
112
|
if ((type as AccountType) === 'ecdsasecp256r1ssh' && !publicKey) {
|
|
110
113
|
const identities = await getIdentities();
|
|
@@ -132,6 +135,7 @@ export function injectCommands(
|
|
|
132
135
|
wait,
|
|
133
136
|
await FeeOptsWithFeePayer.fromCli(options, client, log, db),
|
|
134
137
|
json,
|
|
138
|
+
verbose,
|
|
135
139
|
debugLogger,
|
|
136
140
|
log,
|
|
137
141
|
);
|
|
@@ -154,12 +158,13 @@ export function injectCommands(
|
|
|
154
158
|
'--register-class',
|
|
155
159
|
'Register the contract class (useful for when the contract class has not been deployed yet).',
|
|
156
160
|
)
|
|
157
|
-
.option('--public-deploy', 'Publicly deploy this account contract (only useful if it contains public functions')
|
|
161
|
+
.option('--public-deploy', 'Publicly deploy this account contract (only useful if it contains public functions')
|
|
162
|
+
.addOption(createVerboseOption());
|
|
158
163
|
|
|
159
164
|
addOptions(deployAccountCommand, FeeOptsWithFeePayer.getOptions()).action(async (_options, command) => {
|
|
160
165
|
const { deployAccount } = await import('./deploy_account.js');
|
|
161
166
|
const options = command.optsWithGlobals();
|
|
162
|
-
const { rpcUrl, wait, from: parsedFromAddress, json, registerClass, publicDeploy } = options;
|
|
167
|
+
const { rpcUrl, wait, from: parsedFromAddress, json, registerClass, publicDeploy, verbose } = options;
|
|
163
168
|
|
|
164
169
|
const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger));
|
|
165
170
|
const account = await createOrRetrieveAccount(client, parsedFromAddress, db);
|
|
@@ -171,6 +176,7 @@ export function injectCommands(
|
|
|
171
176
|
publicDeploy,
|
|
172
177
|
await FeeOptsWithFeePayer.fromCli(options, client, log, db),
|
|
173
178
|
json,
|
|
179
|
+
verbose,
|
|
174
180
|
debugLogger,
|
|
175
181
|
log,
|
|
176
182
|
);
|
|
@@ -205,7 +211,8 @@ export function injectCommands(
|
|
|
205
211
|
// https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
|
|
206
212
|
.option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction')
|
|
207
213
|
.option('--no-class-registration', "Don't register this contract class")
|
|
208
|
-
.option('--no-public-deployment', "Don't emit this contract's public bytecode")
|
|
214
|
+
.option('--no-public-deployment', "Don't emit this contract's public bytecode")
|
|
215
|
+
.addOption(createVerboseOption());
|
|
209
216
|
|
|
210
217
|
addOptions(deployCommand, FeeOpts.getOptions()).action(async (artifactPathPromise, _options, command) => {
|
|
211
218
|
const { deploy } = await import('./deploy.js');
|
|
@@ -224,6 +231,7 @@ export function injectCommands(
|
|
|
224
231
|
rpcUrl,
|
|
225
232
|
from: parsedFromAddress,
|
|
226
233
|
alias,
|
|
234
|
+
verbose,
|
|
227
235
|
} = options;
|
|
228
236
|
const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger));
|
|
229
237
|
const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
|
|
@@ -246,6 +254,7 @@ export function injectCommands(
|
|
|
246
254
|
universal,
|
|
247
255
|
wait,
|
|
248
256
|
await FeeOpts.fromCli(options, client, log, db),
|
|
257
|
+
verbose,
|
|
249
258
|
debugLogger,
|
|
250
259
|
log,
|
|
251
260
|
logJson(log),
|
|
@@ -278,7 +287,8 @@ export function injectCommands(
|
|
|
278
287
|
)
|
|
279
288
|
.addOption(createAccountOption('Alias or address of the account to send the transaction from', !db, db))
|
|
280
289
|
.option('--no-wait', 'Print transaction hash without waiting for it to be mined')
|
|
281
|
-
.option('--no-cancel', 'Do not allow the transaction to be cancelled. This makes for cheaper transactions.')
|
|
290
|
+
.option('--no-cancel', 'Do not allow the transaction to be cancelled. This makes for cheaper transactions.')
|
|
291
|
+
.addOption(createVerboseOption());
|
|
282
292
|
|
|
283
293
|
addOptions(sendCommand, FeeOpts.getOptions()).action(async (functionName, _options, command) => {
|
|
284
294
|
const { send } = await import('./send.js');
|
|
@@ -294,6 +304,7 @@ export function injectCommands(
|
|
|
294
304
|
alias,
|
|
295
305
|
cancel,
|
|
296
306
|
authWitness: authWitnessArray,
|
|
307
|
+
verbose,
|
|
297
308
|
} = options;
|
|
298
309
|
const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger));
|
|
299
310
|
const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
|
|
@@ -313,6 +324,7 @@ export function injectCommands(
|
|
|
313
324
|
cancel,
|
|
314
325
|
await FeeOpts.fromCli(options, client, log, db),
|
|
315
326
|
authWitnesses,
|
|
327
|
+
verbose,
|
|
316
328
|
log,
|
|
317
329
|
);
|
|
318
330
|
if (db && sentTx) {
|
|
@@ -321,7 +333,7 @@ export function injectCommands(
|
|
|
321
333
|
}
|
|
322
334
|
});
|
|
323
335
|
|
|
324
|
-
program
|
|
336
|
+
const simulateCommand = program
|
|
325
337
|
.command('simulate')
|
|
326
338
|
.description('Simulates the execution of a function on an Aztec contract.')
|
|
327
339
|
.argument('<functionName>', 'Name of function to simulate')
|
|
@@ -334,26 +346,39 @@ export function injectCommands(
|
|
|
334
346
|
)
|
|
335
347
|
.addOption(createAuthwitnessOption('Authorization witness to use for the simulation', !db, db))
|
|
336
348
|
.addOption(createAccountOption('Alias or address of the account to simulate from', !db, db))
|
|
337
|
-
.
|
|
338
|
-
const { simulate } = await import('./simulate.js');
|
|
339
|
-
const options = command.optsWithGlobals();
|
|
340
|
-
const {
|
|
341
|
-
args,
|
|
342
|
-
contractArtifact: artifactPathPromise,
|
|
343
|
-
contractAddress,
|
|
344
|
-
from: parsedFromAddress,
|
|
345
|
-
rpcUrl,
|
|
346
|
-
secretKey,
|
|
347
|
-
authWitness,
|
|
348
|
-
} = options;
|
|
349
|
+
.addOption(createVerboseOption());
|
|
349
350
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
351
|
+
addOptions(simulateCommand, FeeOpts.getOptions()).action(async (functionName, _options, command) => {
|
|
352
|
+
const { simulate } = await import('./simulate.js');
|
|
353
|
+
const options = command.optsWithGlobals();
|
|
354
|
+
const {
|
|
355
|
+
args,
|
|
356
|
+
contractArtifact: artifactPathPromise,
|
|
357
|
+
contractAddress,
|
|
358
|
+
from: parsedFromAddress,
|
|
359
|
+
rpcUrl,
|
|
360
|
+
secretKey,
|
|
361
|
+
verbose,
|
|
362
|
+
authWitness,
|
|
363
|
+
} = options;
|
|
364
|
+
|
|
365
|
+
const client = (await pxeWrapper?.getPXE()) ?? (await createCompatibleClient(rpcUrl, debugLogger));
|
|
366
|
+
const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
|
|
367
|
+
const wallet = await account.getWallet();
|
|
368
|
+
const artifactPath = await artifactPathFromPromiseOrAlias(artifactPathPromise, contractAddress, db);
|
|
369
|
+
const authWitnesses = cleanupAuthWitnesses(authWitness);
|
|
370
|
+
await simulate(
|
|
371
|
+
wallet,
|
|
372
|
+
functionName,
|
|
373
|
+
args,
|
|
374
|
+
artifactPath,
|
|
375
|
+
contractAddress,
|
|
376
|
+
await FeeOpts.fromCli(options, client, log, db),
|
|
377
|
+
authWitnesses,
|
|
378
|
+
verbose,
|
|
379
|
+
log,
|
|
380
|
+
);
|
|
381
|
+
});
|
|
357
382
|
|
|
358
383
|
const profileCommand = program
|
|
359
384
|
.command('profile')
|
package/src/cmds/profile.ts
CHANGED
|
@@ -1,70 +1,13 @@
|
|
|
1
1
|
import { type AccountWalletWithSecretKey, AuthWitness, type AztecAddress, Contract } from '@aztec/aztec.js';
|
|
2
2
|
import { prepTx } from '@aztec/cli/utils';
|
|
3
3
|
import type { LogFn } from '@aztec/foundation/log';
|
|
4
|
-
import {
|
|
5
|
-
import type { TxProfileResult } from '@aztec/stdlib/tx';
|
|
4
|
+
import { serializePrivateExecutionSteps } from '@aztec/stdlib/kernel';
|
|
6
5
|
|
|
7
6
|
import { promises as fs } from 'fs';
|
|
8
7
|
import path from 'path';
|
|
9
|
-
import { format } from 'util';
|
|
10
8
|
|
|
11
9
|
import type { IFeeOpts } from '../utils/options/fees.js';
|
|
12
|
-
|
|
13
|
-
function printProfileResult(result: TxProfileResult, log: LogFn) {
|
|
14
|
-
log(format('\nPer circuit breakdown:\n'));
|
|
15
|
-
log(
|
|
16
|
-
format(
|
|
17
|
-
' ',
|
|
18
|
-
'Function name'.padEnd(50),
|
|
19
|
-
'Time'.padStart(13).padEnd(15),
|
|
20
|
-
'Gates'.padStart(13).padEnd(15),
|
|
21
|
-
'Subtotal'.padStart(13).padEnd(15),
|
|
22
|
-
),
|
|
23
|
-
);
|
|
24
|
-
log(format(''.padEnd(50 + 15 + 15 + 15 + 15, '-')));
|
|
25
|
-
let acc = 0;
|
|
26
|
-
let biggest: PrivateExecutionStep = result.executionSteps[0] ?? 0;
|
|
27
|
-
|
|
28
|
-
result.executionSteps.forEach(r => {
|
|
29
|
-
if (r.gateCount! > biggest.gateCount!) {
|
|
30
|
-
biggest = r;
|
|
31
|
-
}
|
|
32
|
-
acc += r.gateCount!;
|
|
33
|
-
log(
|
|
34
|
-
format(
|
|
35
|
-
' ',
|
|
36
|
-
r.functionName.padEnd(50),
|
|
37
|
-
`${r.timings.witgen.toFixed(2)}ms`.padStart(13).padEnd(15),
|
|
38
|
-
r.gateCount!.toLocaleString().padStart(13).padEnd(15),
|
|
39
|
-
acc.toLocaleString().padStart(15),
|
|
40
|
-
),
|
|
41
|
-
);
|
|
42
|
-
});
|
|
43
|
-
log(
|
|
44
|
-
format(
|
|
45
|
-
'\nTotal gates:',
|
|
46
|
-
acc.toLocaleString(),
|
|
47
|
-
`(Biggest circuit: ${biggest.functionName} -> ${biggest.gateCount!.toLocaleString()})`,
|
|
48
|
-
),
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
log(format('\nSync time:'.padEnd(25), `${result.timings.sync?.toFixed(2)}ms`.padStart(16)));
|
|
52
|
-
log(
|
|
53
|
-
format(
|
|
54
|
-
'Total simulation time:'.padEnd(25),
|
|
55
|
-
`${result.timings.perFunction.reduce((acc, { time }) => acc + time, 0).toFixed(2)}ms`.padStart(15),
|
|
56
|
-
),
|
|
57
|
-
);
|
|
58
|
-
log(format('Proving time:'.padEnd(25), `${result.timings.proving?.toFixed(2)}ms`.padStart(15)));
|
|
59
|
-
log(
|
|
60
|
-
format(
|
|
61
|
-
'Total time:'.padEnd(25),
|
|
62
|
-
`${result.timings.total.toFixed(2)}ms`.padStart(15),
|
|
63
|
-
`(${result.timings.unaccounted.toFixed(2)}ms unaccounted)`,
|
|
64
|
-
),
|
|
65
|
-
);
|
|
66
|
-
log('\n');
|
|
67
|
-
}
|
|
10
|
+
import { printProfileResult } from '../utils/profiling.js';
|
|
68
11
|
|
|
69
12
|
export async function profile(
|
|
70
13
|
wallet: AccountWalletWithSecretKey,
|
|
@@ -88,7 +31,7 @@ export async function profile(
|
|
|
88
31
|
authWitnesses,
|
|
89
32
|
skipProofGeneration: false,
|
|
90
33
|
});
|
|
91
|
-
printProfileResult(result, log);
|
|
34
|
+
printProfileResult(result.timings, log, result.executionSteps);
|
|
92
35
|
if (debugOutputPath) {
|
|
93
36
|
const ivcInputsPath = path.join(debugOutputPath, 'ivc-inputs.msgpack');
|
|
94
37
|
log(`Debug output written to ${ivcInputsPath}.`);
|
|
@@ -20,7 +20,7 @@ export async function registerContract(
|
|
|
20
20
|
publicKeys?: PublicKeys,
|
|
21
21
|
rawArgs?: any[],
|
|
22
22
|
salt?: Fr,
|
|
23
|
-
deployer?: AztecAddress
|
|
23
|
+
deployer?: AztecAddress,
|
|
24
24
|
) {
|
|
25
25
|
const contractArtifact = await getContractArtifact(artifactPath, log);
|
|
26
26
|
const hasInitializer = getAllFunctionAbis(contractArtifact).some(fn => fn.isInitializer);
|
package/src/cmds/send.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { LogFn } from '@aztec/foundation/log';
|
|
|
11
11
|
import { GasSettings } from '@aztec/stdlib/gas';
|
|
12
12
|
|
|
13
13
|
import { type IFeeOpts, printGasEstimates } from '../utils/options/fees.js';
|
|
14
|
+
import { printProfileResult } from '../utils/profiling.js';
|
|
14
15
|
|
|
15
16
|
export async function send(
|
|
16
17
|
wallet: AccountWalletWithSecretKey,
|
|
@@ -22,6 +23,7 @@ export async function send(
|
|
|
22
23
|
cancellable: boolean,
|
|
23
24
|
feeOpts: IFeeOpts,
|
|
24
25
|
authWitnesses: AuthWitness[],
|
|
26
|
+
verbose: boolean,
|
|
25
27
|
log: LogFn,
|
|
26
28
|
) {
|
|
27
29
|
const { functionArgs, contractArtifact } = await prepTx(contractArtifactPath, functionName, functionArgsIn, log);
|
|
@@ -45,7 +47,12 @@ export async function send(
|
|
|
45
47
|
return;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
|
-
const
|
|
50
|
+
const provenTx = await call.prove(sendOptions);
|
|
51
|
+
if (verbose) {
|
|
52
|
+
printProfileResult(provenTx.timings!, log);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const tx = provenTx.send();
|
|
49
56
|
const txHash = await tx.getTxHash();
|
|
50
57
|
log(`\nTransaction hash: ${txHash.toString()}`);
|
|
51
58
|
if (wait) {
|
package/src/cmds/simulate.ts
CHANGED
|
@@ -4,19 +4,31 @@ import type { LogFn } from '@aztec/foundation/log';
|
|
|
4
4
|
|
|
5
5
|
import { format } from 'util';
|
|
6
6
|
|
|
7
|
+
import type { IFeeOpts } from '../utils/options/fees.js';
|
|
8
|
+
import { printProfileResult } from '../utils/profiling.js';
|
|
9
|
+
|
|
7
10
|
export async function simulate(
|
|
8
11
|
wallet: AccountWalletWithSecretKey,
|
|
9
12
|
functionName: string,
|
|
10
13
|
functionArgsIn: any[],
|
|
11
14
|
contractArtifactPath: string,
|
|
12
15
|
contractAddress: AztecAddress,
|
|
16
|
+
feeOpts: IFeeOpts,
|
|
13
17
|
authWitnesses: AuthWitness[],
|
|
18
|
+
verbose: boolean,
|
|
14
19
|
log: LogFn,
|
|
15
20
|
) {
|
|
16
21
|
const { functionArgs, contractArtifact } = await prepTx(contractArtifactPath, functionName, functionArgsIn, log);
|
|
17
22
|
|
|
18
23
|
const contract = await Contract.at(contractAddress, contractArtifact, wallet);
|
|
19
24
|
const call = contract.methods[functionName](...functionArgs);
|
|
20
|
-
const
|
|
21
|
-
|
|
25
|
+
const simulationResult = await call.simulate({
|
|
26
|
+
...(await feeOpts.toSendOpts(wallet)),
|
|
27
|
+
authWitnesses,
|
|
28
|
+
includeMetadata: true,
|
|
29
|
+
});
|
|
30
|
+
if (verbose) {
|
|
31
|
+
printProfileResult(simulationResult.meta.timings!, log);
|
|
32
|
+
}
|
|
33
|
+
log(format('\nSimulation result: ', simulationResult.result, '\n'));
|
|
22
34
|
}
|