-
Notifications
You must be signed in to change notification settings - Fork 126
Transaction gas costs
This Dune query can be used to collect block stats: https://explore.duneanalytics.com/queries/19430/source
This query returns stats for all blocks of block size 386 in the last 7 days, containing 262 blocks when I executed the query.
Data can be pasted in a worksheet and saved as block_stats.csv
. My data can be downloaded here: https://drive.google.com/file/d/1QRjag7wwgNlzRWYVh14H_1EXXOhwcbdp/view?usp=sharing
The following python script can be used to run over a bunch of parameters to find the closest fit. An extra penalty can be given to predictions that are lower than the actual gas used by the block.
import csv
from collections import namedtuple
MyStruct = namedtuple("BlockStats", "gas_used num_noops num_deposits num_withdrawals num_transfers num_trades num_account_updates num_amm_updates num_signatures")
with open('block_stats.csv', newline='') as csvfile:
csv_reader = csv.reader(csvfile, delimiter=',', quotechar='"')
block_stats = []
line_count = 0
for row in csv_reader:
if line_count == 0:
print(f'Column names are {", ".join(row)}')
line_count += 1
else:
line_count += 1
block_stat = MyStruct(int(row[1]), int(row[2]), int(row[3]), int(row[4]), int(row[5]), int(row[6]), int(row[7]), int(row[8]), int(row[9]))
block_stats.append(block_stat)
print(f'Processed {line_count} lines.')
best_total_error = 2**32
best_noop_cost = 0
best_deposit_cost = 0
best_withdrawal_cost = 0
best_transfer_cost = 0
best_trade_cost= 0
best_account_update_cost = 0
best_amm_update_cost = 0
best_signature_cost = 0
'''
# Used to roughly find good values
for noop_cost in range(0, 2000, 200):
print("**noop_cost**: " + str(noop_cost))
for deposit_cost in range(-10000, 10000, 2000):
print("**deposit_cost**: " + str(deposit_cost))
for withdrawal_cost in range(30000, 60000, 5000):
print("**withdrawal_cost**: " + str(withdrawal_cost))
for transfer_cost in range(400, 2000, 200):
for trade_cost in range(400, 2000, 200):
for account_update_cost in range(5000, 20000, 2000):
for amm_update_cost in range(30000, 70000, 5000):
for signature_cost in range(1000, 10000, 2000):
'''
'''
# Used to more accurately find the better values
for noop_cost in range(800, 1300, 100):
print("**noop_cost**: " + str(noop_cost))
for deposit_cost in range(-2000, 2000, 1000):
print("**deposit_cost**: " + str(deposit_cost))
for withdrawal_cost in range(42000, 48000, 1000):
print("**withdrawal_cost**: " + str(withdrawal_cost))
for transfer_cost in range(1000, 1500, 100):
for trade_cost in range(1000, 1500, 100):
for account_update_cost in range(13000, 17000, 1000):
for amm_update_cost in range(40000, 50000, 1000):
for signature_cost in range(1000, 9000, 1000):
'''
# Used to find the best values
for noop_cost in range(1000, 1300, 50):
print("**noop_cost**: " + str(noop_cost))
for deposit_cost in range(-1000, 1000, 500):
print("**deposit_cost**: " + str(deposit_cost))
for withdrawal_cost in range(45000, 48000, 500):
print("**withdrawal_cost**: " + str(withdrawal_cost))
for transfer_cost in range(1200, 1450, 50):
for trade_cost in range(1200, 1450, 50):
for account_update_cost in range(15000, 19000, 500):
for amm_update_cost in range(45000, 48000, 500):
for signature_cost in range(3500, 6000, 500):
total_error = 0
# Run over all blocks
for stat in block_stats:
prediction = noop_cost * stat.num_noops + \
deposit_cost * stat.num_deposits + \
withdrawal_cost * stat.num_withdrawals + \
transfer_cost * stat.num_transfers + \
trade_cost * stat.num_trades + \
account_update_cost * stat.num_account_updates + \
amm_update_cost * stat.num_amm_updates + \
signature_cost * stat.num_signatures
error = abs(prediction - stat.gas_used)
# Extra penalty for predictions that are too low
if prediction < stat.gas_used:
error = error*4
# accumulate error
total_error = total_error + error
# Check total error
if total_error < best_total_error:
best_total_error = total_error
best_noop_cost = noop_cost
best_deposit_cost = deposit_cost
best_withdrawal_cost = withdrawal_cost
best_transfer_cost = transfer_cost
best_trade_cost = trade_cost
best_account_update_cost = account_update_cost
best_amm_update_cost = amm_update_cost
best_signature_cost = signature_cost
print("best error updated: " + str(total_error))
print("- noop_cost: " + str(best_noop_cost))
print("- deposit_cost: " + str(best_deposit_cost))
print("- withdrawal_cost: " + str(best_withdrawal_cost))
print("- transfer_cost: " + str(best_transfer_cost))
print("- trade_cost: " + str(best_trade_cost))
print("- account_update_cost: " + str(best_account_update_cost))
print("- amm_update_cost: " + str(best_amm_update_cost))
print("- signature_cost: " + str(best_signature_cost))
print("Best total error: " + str(best_total_error))
print("- noop_cost: " + str(best_noop_cost))
print("- deposit_cost: " + str(best_deposit_cost))
print("- withdrawal_cost: " + str(best_withdrawal_cost))
print("- transfer_cost: " + str(best_transfer_cost))
print("- trade_cost: " + str(best_trade_cost))
print("- account_update_cost: " + str(best_account_update_cost))
print("- amm_update_cost: " + str(best_amm_update_cost))
print("- signature_cost: " + str(best_signature_cost))
The error rate can be visualised on Dune: https://explore.duneanalytics.com/queries/19403/source#39659
A positive error means the predicted gas usage is higher than the actual gas used. A negative error means the prediction gas usage is lower than the actual gas used.
Best total error: 6062210
- noop_cost: 1100
- deposit_cost: -1000
- withdrawal_cost: 45500
- transfer_cost: 1350
- trade_cost: 1350
- account_update_cost: 16000
- amm_update_cost: 46000
- signature_cost: 5000
Best total error: 8143239
- noop_cost: 1200
- deposit_cost: -500
- withdrawal_cost: 46500
- transfer_cost: 1350
- trade_cost: 1350
- account_update_cost: 17500
- amm_update_cost: 46000
- signature_cost: 5000
Error rate x4
Best total error: 10378752
- noop_cost: 1100
- deposit_cost: 500
- withdrawal_cost: 47500
- transfer_cost: 1350
- trade_cost: 1350
- account_update_cost: 17000
- amm_update_cost: 46500
- signature_cost: 5000
The average gas costs provide a very good fit to the actual gas used.
Good average gas costs for operations are:
- Withdrawal: 45,500-47,500 gas
- Transfer: 1,350 gas
- Trade: 1,350 gas
- Account Update: 16,000-17,000 gas
- AMM join/AMM exit: 101,000 - 102,000 gas
An AMM join/exit is: 2x AMM updates + 3x transfers + 1x signature verification
Once compression is enabled gas costs for noops/trades/transfers should go down. Submitting multiple blocks at once when we have enough throughput will also lower gas costs.
Loopring Foundation
nothing here