Gno Fee Taskforce WIP Goal
Find how much gas is used for common types of transactions
Estimate the amount of transactions of each type can be done by an average GNOT token holder
Recommend gas fee adjustments
Total number of accounts: 656,740
Totals
All: 752,454,999,663,089 ugnot
Top 1000 accounts: 621,654,079,086,191 ugnot
Bottom 1000 accounts: 2,000 ugnot
All excluding the top and bottom 1000: 130,800,920,574,898 ugnot
Weight
Top 1000 accounts (0.15% of the total number of accounts) hold 82.62% of the total balance
Bottom 1000 accounts (0.15% of the total number of accounts) hold 0.0000000003% of the total balance
Averages
All: 1,145,742,606.91 ugnot
Top 1000 accounts: 621,654,079,086.19 ugnot
Bottom 1000 accounts: 2.00 ugnot
All excluding the top and bottom 1000: 199,775,362.09 ugnot
Spread
Variance of balances: 18,446,744,073,709,551,615
Standard deviation of balances: 4,294,967,296
Percentiles
99th percentile of balances: 4,060,691,105 ugnot
95th percentile of balances: 552,862,608 ugnot
90th percentile of balances: 239,673,979 ugnot
75th percentile of balances: 52,359,891 ugnot
50th percentile of balances: 8,388,001 ugnot (median)
25th percentile of balances: 194,150 ugnot
10th percentile of balances: 7,496 ugnot
5th percentile of balances: 4,872 ugnot
1st percentile of balances: 9 ugnot
Gas usage
Global average cost: 6,744,429 ugnot
Median user (50th percentile) can call 1.24 times
Bottom quarter user (25th percentile) can call 0.03 times
Average user can call 169.88 times
Average (excluding top and bottom 1000) can call 29.62 times
Bank transfer
Average cost: 45,116 ugnot
Median user (50th percentile) can transfer 185.92 times
Bottom quarter user (25th percentile) can transfer 4.30 times
Average user can transfer 25,395.48 times
Average (excluding top and bottom 1000) can transfer 4,428.04 times
Realm "gno.land/r/demo/boards"
Realm average cost: 6,357,615 ugnot
Median user (50th percentile) can call 1.32 times
Bottom quarter user (25th percentile) can call 0.03 times
Average user can call 180.22 times
Average (excluding top and bottom 1000) can call 31.42 times
Func "CreateBoard"
Func "CreateBoard" average cost: 10,282,870 ugnot
Median user (50th percentile) can call 0.82 times
Bottom quarter user (25th percentile) can call 0.02 times
Average user can call 111.42 times
Average (excluding top and bottom 1000) can call 19.43 times
Func "GetBoardIDFromName"
Func "GetBoardIDFromName" average cost: 1,137,910 ugnot
Median user (50th percentile) can call 7.37 times
Bottom quarter user (25th percentile) can call 0.17 times
Average user can call 1,006.88 times
Average (excluding top and bottom 1000) can call 175.56 times
Func "CreateThread"
Func "CreateThread" average cost: 6,821,067 ugnot
Median user (50th percentile) can call 1.23 times
Bottom quarter user (25th percentile) can call 0.03 times
Average user can call 167.97 times
Average (excluding top and bottom 1000) can call 29.29 times
Func "CreateReply"
Func "CreateReply" average cost: 6,983,445 ugnot
Median user (50th percentile) can call 1.20 times
Bottom quarter user (25th percentile) can call 0.03 times
Average user can call 164.07 times
Average (excluding top and bottom 1000) can call 28.61 times
Func "DeletePost"
Func "DeletePost" average cost: 6,562,785 ugnot
Median user (50th percentile) can call 1.28 times
Bottom quarter user (25th percentile) can call 0.03 times
Average user can call 174.58 times
Average (excluding top and bottom 1000) can call 30.44 times
Realm "gno.land/r/demo/grc20factory"
Realm average cost: 7,131,244 ugnot
Median user (50th percentile) can call 1.18 times
Bottom quarter user (25th percentile) can call 0.03 times
Average user can call 160.67 times
Average (excluding top and bottom 1000) can call 28.01 times
Func "NewWithAdmin"
Func "NewWithAdmin" average cost: 7,538,156 ugnot
Median user (50th percentile) can call 1.11 times
Bottom quarter user (25th percentile) can call 0.03 times
Average user can call 151.99 times
Average (excluding top and bottom 1000) can call 26.50 times
Func "Mint"
Func "Mint" average cost: 6,575,337 ugnot
Median user (50th percentile) can call 1.28 times
Bottom quarter user (25th percentile) can call 0.03 times
Average user can call 174.25 times
Average (excluding top and bottom 1000) can call 30.38 times
Func "Burn"
Func "Burn" average cost: 6,198,809 ugnot
Median user (50th percentile) can call 1.35 times
Bottom quarter user (25th percentile) can call 0.03 times
Average user can call 184.83 times
Average (excluding top and bottom 1000) can call 32.23 times
Func "Transfer"
Func "Transfer" average cost: 8,212,674 ugnot
Median user (50th percentile) can call 1.02 times
Bottom quarter user (25th percentile) can call 0.02 times
Average user can call 139.51 times
Average (excluding top and bottom 1000) can call 24.33 times
Onbloc Research & Notes Gno Transaction Fee Comparison in Devnet
General Transfer:
Fee: 0.000115 GNOT
Used/Wanted: 47,066/55,015 (85.55%)
Mint Transaction (GnoSwap):
Fee: 0.405793 GNOT
Used/Wanted: 162,318,280/194,780,448 (83.33%)
The Mint transaction consumes about x3500 more fees than a general GNOT transfer transaction
Even if the Mint transaction requires complex computation such as uint256, this gap is too large and seems abnormal.
A simple direct swap (not a complex routed swap) consumes 0.251787 GNOT, Used/Wanted of (100,715,640/120,857,292 (83.33%).
Transaction Fee Comparison in Portal-loop
General Transfer:
Fee: 0.000114 GNOT
Used/Wanted: 44,310/54,271 (81.65%)
Deposit (r/demo/wugnot, a simple contract):
Fee: 0.01727 GNOT
Used/Wanted: 6,908,950/8,289,264 (83.35%)
A simple contract use consumes x151 more gas than a general transfer.
Realm Package: gno.land/r/demo/wugnot
Function: Deposit
gnokey maketx call \
-pkgpath "gno.land/r/demo/wugnot" \
-func "Deposit" \
-send "1000ugnot" \
-gas-fee 1000000ugnot \
-gas-wanted 20000000 \
-broadcast \
-chainid dev \
test1
Gas consumption by item
description: ReadFlat , consumed: 10000
description: WriteFlat , consumed: 10000
description: WritePerByte , consumed: 17610
description: ante verify: secp256k1 , consumed: 1000
description: GetPackageRealmPerByte , consumed: 35632
description: SetObjectPerByte , consumed: 31360
description: txSize , consumed: 2510
description: ReadPerByte , consumed: 3522
description: GetObjectPerByte , consumed: 2668848
description: CPUCycles , consumed: 158313
description: SetPackageRealmPerByte , consumed: 35632
description: DeleteObjectFlat , consumed: 7430
Gas consumption is about 89.5% being consumed by the item called GetObjectPerByte.
Items that load the VM’s state objects
Consuming gas to load objects seems like a reasonable gas consumption.
However, the gas weight of GetObjectPerByte
is multiplied by 16
and is consuming a lot of gas.
I have a couple questions here.
I’ll have to track what is being loaded further, but is a weight of 16
appropriate?
Giuseppe / Milos gas fee message Here is where we do the fee validation:
https://github.com/gnolang/gno/blob/6f91a35f3fcb0da593a8b45f6b19d70865406e05/tm2/pkg/sdk/auth/ante.go#L333-L406
The block gas context value is set in the app setup:
https://github.com/gnolang/gno/blob/6f91a35f3fcb0da593a8b45f6b19d70865406e05/gno.land/pkg/gnoland/app.go#L124-L125
the initial value of the block gas context (price) is set in the init chainer:
https://github.com/gnolang/gno/blob/6f91a35f3fcb0da593a8b45f6b19d70865406e05/gno.land/pkg/gnoland/app.go#L330-L331
this param value is set in the initial auth params:
https://github.com/gnolang/gno/blob/6f91a35f3fcb0da593a8b45f6b19d70865406e05/tm2/pkg/sdk/auth/params.go#L34 (by default it's 0.001ugnot/gas, it's part of the genesis state in genesis.json):
"auth" : {
"params" : {
"max_memo_bytes" : "65536" ,
"tx_sig_limit" : "7" ,
"tx_size_cost_per_byte" : "10" ,
"sig_verify_cost_ed25519" : "590" ,
"sig_verify_cost_secp256k1" : "1000" ,
"gas_price_change_compressor" : "10" ,
"target_gas_ratio" : "70" ,
"initial_gasprice" : {
"gas" : "1000" ,
"price" : "1ugnot"
}
}
}
This block-level gas price is updated in the EndBlocker logic:
https://github.com/gnolang/gno/blob/6f91a35f3fcb0da593a8b45f6b19d70865406e05/tm2/pkg/sdk/auth/keeper.go#L195-L205
The validators set the target gas ratio to move the minimum network gas fee up or down (check calcBlockGasPrice
).
This value is updated through the params keeper, which we can call through governance proposals in gno code
The node-specific gas limit is also set in the app setup (config.toml param):
https://github.com/gnolang/gno/blob/6f91a35f3fcb0da593a8b45f6b19d70865406e05/gno.land/pkg/gnoland/app.go#L88 .
Node operators can update this at any time before they start their node
@Ray Qin can correct me if I missed something in haste, but this should be it:
network (block) gas fee limits are controlled through governance (govdao), using the params module. Initial state set in genesis state
validator (node) gas fee limits are set through the config.toml , and are node-specific