Profiling Transactions
An Aztec transaction typically consists of a private and a public part. The private part is where the user executes contract logic within the PXE and generates a proof of execution, which is then sent to the sequencer.
Since proof generation is an expensive operation that needs to be done on the client side, it is important to optimize the private contract logic. It is desirable to keep the gate count of circuits representing the private contract logic as low as possible.
A private transaction can involve multiple function calls. It starts with an account entrypoint()
which may call several private functions to execute the application logic, which in turn might call other functions. Moreover, every private function call has to go through a round of kernel circuits. Read more about the transaction lifecycle here.
In this guide, we will look at how to profile the private execution of a transaction, allowing you to get the gate count of each private function within the transaction, including the kernel circuits.
Prerequisites
aztec-nargo
installed (go to Sandbox section for installation instructions)aztec-wallet
installed (installed as part of the Sandbox)
Profiling using aztec-wallet
The profiling tool is integrated into the aztec-wallet
.
In this example, we will profile a simple "private token transfer" transaction which uses the transfer method in the token contract. Let us start by deploying the token contarct (included in the Sandbox) and minting some tokens to the test account.
# Import some test accounts included in cli-wallet
aztec-wallet import-test-accounts
# Deploy a token contract.
aztec-wallet deploy TokenContractArtifact --from accounts:test0 --args accounts:test0 TestToken TST 18 -a token
# Mint some tokens to the test0 account
aztec-wallet send mint_to_private -ca token --args accounts:test0 accounts:test0 100 -f test0
Now, the test0
account can transfer tokens by running:
# Send 40 tokens from test0 to test1
aztec-wallet send transfer -ca token --args accounts:test1 40 -f accounts:test0
Instead of sending the above transaction, you can profile it by running the profile
command with the same parameters.
aztec-wallet profile transfer -ca token --args accounts:test1 40 -f accounts:test0
This will print the following results after some time:
Gate count per circuit:
SchnorrAccount:entrypoint Gates: 21,724 Acc: 21,724
private_kernel_init Gates: 45,351 Acc: 67,075
Token:transfer Gates: 31,559 Acc: 98,634
private_kernel_inner Gates: 78,452 Acc: 177,086
private_kernel_reset Gates: 91,444 Acc: 268,530
private_kernel_tail Gates: 31,201 Acc: 299,731
Total gates: 299,731
Here you can see the gate count of each private function call in the transaction along with the kernel circuits needed in between, and the total gate count.
This will help you understand which parts of your transaction are bottlenecks and optimize the contract logic accordingly.
Flamegraph
While the aztec-wallet
provides a way to profile the gate count of each private function in a transaction, flamegraph tool lets you visualize the gate count of each operation within a private function.
You can run the flamegraph tool by running the following command:
aztec flamegraph <artifact_path> <function_name>
For example, if you want to flamegraph the cast_vote
function aztec-starter, you can do
aztec-nargo compile
aztec flamegraph target/easy_private_voting_contract-EasyPrivateVoting.json cast_vote
This will generate a flamegraph of the cast_vote
function and save the output svg to the target
directory. You can open the svg file in your browser to visualize the flamegraph.
You can also run the same command with SERVE=1
to serve the flamegraph on a local server.
SERVE=1 aztec flamegraph target/easy_private_voting_contract-EasyPrivateVoting.json cast_vote
This will serve the flamegraph on http://localhost:8000
.