-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgolem-price-update.py
executable file
·119 lines (99 loc) · 5.01 KB
/
golem-price-update.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/local/bin/python3
import requests
import os
import argparse
import subprocess
import random
def parse_args():
parser = argparse.ArgumentParser(
description="automatically adjust golem provider prices. GLM Price provided by CoinGecko")
parser.add_argument("--currency", type=str, help="desired fiat currency for prices, default: USD", default="USD")
# TODO: if there's some kind of API for getting your local electricty costs feel free to submit a PR
parser.add_argument("--price_kwh", type=float, help="electricity price per kwH in your fiat currency, default: 0.1",
default=0.1)
parser.add_argument("-w", "--watts", type=int, help="power usage of your provider in watts, default: 150",
default=150)
parser.add_argument("--idle", type=int, help="power usage of your provider in watts at idle."
"used to calculate env/hr rate."
"If not provided, env/hr will be 0 and all earnings will be from cpu/hr",
default=0)
# TODO: add option to target earnings that could have been made by mining a coin/other workload
parser.add_argument("-p", "--profit", type=float,
help="desired additional profit beyond electricity costs, (1.0 is 100 percent), default: 0.1 (10 percent)",
default=0.1)
parser.add_argument("-t", "--threads", type=int, help='''number of threads on golem provider. \n
t = 0 is all threads. \n
t < 0 is t less that all threads. \n
t > 1 is t threads. \n
if t is higher than available threads, maximum of all threads will be used. \n
if all threads - t is less than 1, 1 thread will be used. \n
default: all threads''', default=0)
parser.add_argument("-u", "--update_cron", action="store_true",
help="run this script every hour with the same settings by adding it to the cron file")
parser.add_argument("--dry_run", action="store_true",
help="display result but do not actually update, (applied to cron setting as well)")
# TODO: add option to go based off of prices of similar nodes instead of electricty cost
return parser.parse_args()
def print_arg(k, v) -> str:
if type(v) is bool:
if v:
return f"--{k}"
else:
return ""
return f"--{k} {v}"
if __name__ == "__main__":
args = parse_args()
if args.update_cron:
try:
from crontab import CronTab
from crontabs import CronTabs
except ModuleNotFoundError:
print("")
print("module `python-crontab` is required to update the crontab, it can be installed with:")
print("")
print("pip3 install python-crontab")
print("")
exit(0)
args_dict = vars(args)
del args_dict["update_cron"]
cmd = f"{os.path.abspath(__file__)} {' '.join([print_arg(k, v) for k, v in args_dict.items()])} > /dev/null 2>&1"
comment = "update GLM price, set by script"
cron = CronTab(user=True)
job = cron.new(command=cmd, comment=comment)
# TODO make this settable by an arg
job.minute.on(random.randint(0, 59))
job.hour.every(1)
print("removing the following jobs from crontab")
print(*cron.find_comment(comment), sep="\n")
print("adding the following to cron tab:")
print(job)
if not args.dry_run:
# remove old job
cron.remove_all(comment=comment)
cron.append(job)
cron.write()
request = requests.get(f"https://api.coingecko.com/api/v3/simple/price?ids=golem&vs_currencies={args.currency}")
json_data = request.json()
glm_price = json_data["golem"][args.currency.lower()]
num_threads = os.cpu_count()
if args.threads > 0:
num_threads = min(os.cpu_count(), args.threads)
if args.threads < 0:
num_threads = max(os.cpu_count() + args.threads, 1)
load_watts = args.watts - args.idle
cost_per_hour_load = (load_watts * 0.001) * args.price_kwh
desired_income_per_hour = cost_per_hour_load * (1 + args.profit)
price_per_thread_fiat = desired_income_per_hour / num_threads
price_per_thread_glm = price_per_thread_fiat * (1 / glm_price)
cost_per_hour_idle = (args.idle * 0.001) * args.price_kwh
price_per_env_fiat = cost_per_hour_idle * (1 + args.profit)
price_per_env_glm = price_per_env_fiat * (1 / glm_price)
# print the price to show the user
print("CPU per hour:", price_per_thread_glm)
print("ENV per hour:", price_per_env_glm)
if not args.dry_run:
# set the price
golem_path = os.path.expanduser("~/.local/bin/golemsp")
subprocess.call([golem_path, "settings", "set", "--cpu-per-hour", str(price_per_thread_glm)])
subprocess.call([golem_path, "settings", "set", "--env-per-hour", str(price_per_env_glm)])
subprocess.call([golem_path, "settings", "set", "--starting-fee", "0"])