-
Notifications
You must be signed in to change notification settings - Fork 66
A0-1766: Sketch out the pricing script #852
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
44c612f
5310663
7b8b596
88a870f
0ee87a8
8cba8da
b2a0910
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
Pricing script | ||
============== | ||
|
||
The `./run.py` script in this directory will deploy some contracts and print a summary of how much some basic operations | ||
on them cost. | ||
|
||
It requires `python3` and an Ink 4-compatible version of `cargo contract`, to install: | ||
|
||
```bash | ||
$ cargo install cargo-contract --version 2.0.0-beta.1 | ||
``` | ||
|
||
Afterwards, install the python deps and run the script: | ||
|
||
```bash | ||
$ pip install -r requirements.txt | ||
$ ./run.py | ||
``` | ||
|
||
For more info on options see: | ||
|
||
```bash | ||
$ ./run.py --help | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
tabulate==0.9.0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
#!/usr/bin/python3 | ||
|
||
import argparse | ||
import random | ||
import subprocess | ||
import json | ||
from tabulate import tabulate | ||
import urllib.request | ||
|
||
AZERO = 1_000_000_000_000 | ||
|
||
|
||
parser = argparse.ArgumentParser( | ||
description='Check the prices of some common contract operations') | ||
parser.add_argument('--url', type=str, | ||
default='ws://localhost:9944', help='URL of the node to connect to') | ||
parser.add_argument('--suri', type=str, default='//Alice', | ||
help='Secret key URI to use for calls') | ||
parser.add_argument('--adder-dir', type=str, | ||
help='Directory of the adder contract', default='../../contracts/adder') | ||
|
||
args = parser.parse_args() | ||
|
||
COMMON_ARGS = ['--suri', args.suri, '--url', | ||
args.url, '--skip-confirm', '--output-json'] | ||
|
||
|
||
def random_salt(): | ||
return ''.join(random.choice('0123456789abcdef') for _ in range(10)) | ||
|
||
|
||
def deploy(directory): | ||
res = subprocess.check_output(['cargo', 'contract', 'instantiate', '--salt', | ||
random_salt()] + COMMON_ARGS, cwd=directory) | ||
return json.loads(res.decode('utf-8')) | ||
|
||
|
||
def call(directory, contract, message, *args): | ||
args = [x for a in args for x in ['--args', a]] | ||
res = subprocess.check_output(['cargo', 'contract', 'call', '--contract', contract, | ||
'--message', message] + args + COMMON_ARGS, cwd=directory) | ||
return json.loads(res.decode('utf-8')) | ||
|
||
|
||
def event_field(event, field): | ||
for f in event['fields']: | ||
if f['name'] == field: | ||
return f['value'] | ||
|
||
|
||
def deployer_account_id(deploy_result): | ||
setup_event = next(filter( | ||
lambda e: e['name'] == 'Transfer' and account_id(event_field(e, 'to')) == adder_address, deploy_result['events']), None) | ||
|
||
return account_id(event_field(setup_event, 'from')) | ||
|
||
|
||
def account_id(value): | ||
match value: | ||
case {'Literal': account_id}: return account_id | ||
case _: raise ValueError(f'Invalid account id: {value}') | ||
|
||
|
||
def uint(value): | ||
match value: | ||
case {'UInt': value}: return value | ||
case _: raise ValueError(f'Invalid uint: {value}') | ||
|
||
|
||
def find_fee(events, by_whom): | ||
fee_event = next(filter(lambda e: e['name'] == 'TransactionFeePaid' and account_id( | ||
event_field(e, 'who')) == by_whom, events), None) | ||
return uint(event_field(fee_event, 'actual_fee')) | ||
|
||
|
||
with urllib.request.urlopen('https://api.coingecko.com/api/v3/simple/price?ids=aleph-zero&vs_currencies=usd') as response: | ||
data = json.load(response) | ||
aleph_usd = data['aleph-zero']['usd'] | ||
|
||
|
||
def format_fee(fee): | ||
return "%f AZERO ($%f)" % (fee / AZERO, fee / AZERO * aleph_usd) | ||
|
||
|
||
deploy_result = deploy(args.adder_dir) | ||
|
||
adder_address = deploy_result['contract'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This approach will return invalid address if there are contracts instantiated in the constructor use-ink/cargo-contract#777 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, given it's a bug in cargo contract, I say ignore until they fix it, then update cargo contract, no? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or you can inspect the You will handle it however you want, I'm just raising a problem this code has with some contracts. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll keep that in mind if I run into this problem. |
||
suri_address = deployer_account_id(deploy_result) | ||
instantiate_fee = find_fee(deploy_result['events'], suri_address) | ||
|
||
events = call(args.adder_dir, adder_address, 'add', '42') | ||
add_fee = find_fee(events, suri_address) | ||
|
||
headers = ['Operation', 'Fee'] | ||
prices = [ | ||
["Instantiate contract with single storage value", | ||
format_fee(instantiate_fee)], | ||
["Call contract with single storage update", format_fee(add_fee)] | ||
] | ||
|
||
print(tabulate(prices, headers=headers, tablefmt="github")) |
Uh oh!
There was an error while loading. Please reload this page.