Create msgspec struct for config

pull/47/head
Guillermo Rodriguez 2025-02-07 15:07:48 -03:00
parent 5a3a43b3c6
commit ea3b35904c
No known key found for this signature in database
GPG Key ID: 002CC5F1E6BDA53E
5 changed files with 129 additions and 331 deletions

View File

@ -13,7 +13,6 @@ from leap.protocol import (
from .config import ( from .config import (
load_skynet_toml, load_skynet_toml,
load_key,
set_hf_vars, set_hf_vars,
ConfigParsingError, ConfigParsingError,
) )
@ -49,9 +48,7 @@ def txt2img(*args, **kwargs):
from . import utils # TODO? why here, import cycle? from . import utils # TODO? why here, import cycle?
config = load_skynet_toml() config = load_skynet_toml()
hf_token = load_key(config, 'skynet.dgpu.hf_token') set_hf_vars(config.dgpu.hf_token, config.dgpu.hf_home)
hf_home = load_key(config, 'skynet.dgpu.hf_home')
set_hf_vars(hf_token, hf_home)
utils.txt2img(hf_token, **kwargs) utils.txt2img(hf_token, **kwargs)
@ -75,9 +72,7 @@ def txt2img(*args, **kwargs):
def img2img(model, prompt, input, output, strength, guidance, steps, seed): def img2img(model, prompt, input, output, strength, guidance, steps, seed):
from . import utils from . import utils
config = load_skynet_toml() config = load_skynet_toml()
hf_token = load_key(config, 'skynet.dgpu.hf_token') set_hf_vars(config.dgpu.hf_token, config.dgpu.hf_home)
hf_home = load_key(config, 'skynet.dgpu.hf_home')
set_hf_vars(hf_token, hf_home)
utils.img2img( utils.img2img(
hf_token, hf_token,
model=model, model=model,
@ -105,9 +100,7 @@ def img2img(model, prompt, input, output, strength, guidance, steps, seed):
def inpaint(model, prompt, input, mask, output, strength, guidance, steps, seed): def inpaint(model, prompt, input, mask, output, strength, guidance, steps, seed):
from . import utils from . import utils
config = load_skynet_toml() config = load_skynet_toml()
hf_token = load_key(config, 'skynet.dgpu.hf_token') set_hf_vars(config.dgpu.hf_token, config.dgpu.hf_home)
hf_home = load_key(config, 'skynet.dgpu.hf_home')
set_hf_vars(hf_token, hf_home)
utils.inpaint( utils.inpaint(
hf_token, hf_token,
model=model, model=model,
@ -137,113 +130,15 @@ def upscale(input, output, model):
def download(): def download():
from . import utils from . import utils
config = load_skynet_toml() config = load_skynet_toml()
hf_token = load_key(config, 'skynet.dgpu.hf_token') set_hf_vars(config.dgpu.hf_token, config.dgpu.hf_home)
hf_home = load_key(config, 'skynet.dgpu.hf_home') utils.download_all_models(config.dgpu.hf_token, config.dgpu.hf_home)
set_hf_vars(hf_token, hf_home)
utils.download_all_models(hf_token, hf_home)
@skynet.command()
@click.option(
'--reward', '-r', default='20.0000 GPU')
@click.option('--jobs', '-j', default=1)
@click.option('--model', '-m', default='stabilityai/stable-diffusion-xl-base-1.0')
@click.option(
'--prompt', '-p', default='a red old tractor in a sunny wheat field')
@click.option('--output', '-o', default='output.png')
@click.option('--width', '-w', default=1024)
@click.option('--height', '-h', default=1024)
@click.option('--guidance', '-g', default=10)
@click.option('--step', '-s', default=26)
@click.option('--seed', '-S', default=None)
@click.option('--upscaler', '-U', default='x4')
@click.option('--binary_data', '-b', default='')
@click.option('--strength', '-Z', default=None)
def enqueue(
reward: str,
jobs: int,
**kwargs
):
import trio
from leap.cleos import CLEOS
config = load_skynet_toml()
key = load_key(config, 'skynet.user.key')
account = load_key(config, 'skynet.user.account')
permission = load_key(config, 'skynet.user.permission')
node_url = load_key(config, 'skynet.user.node_url')
cleos = CLEOS(None, None, url=node_url, remote=node_url)
binary = kwargs['binary_data']
if not kwargs['strength']:
if binary:
raise ValueError('strength -Z param required if binary data passed')
del kwargs['strength']
else:
kwargs['strength'] = float(kwargs['strength'])
async def enqueue_n_jobs():
for i in range(jobs):
if not kwargs['seed']:
kwargs['seed'] = random.randint(0, 10e9)
req = json.dumps({
'method': 'diffuse',
'params': kwargs
})
res = await cleos.a_push_action(
'gpu.scd',
'enqueue',
{
'user': Name(account),
'request_body': req,
'binary_data': binary,
'reward': Asset.from_str(reward),
'min_verification': 1
},
account, key, permission,
)
print(res)
trio.run(enqueue_n_jobs)
@skynet.command()
@click.option('--loglevel', '-l', default='INFO', help='Logging level')
def clean(
loglevel: str,
):
import trio
from leap.cleos import CLEOS
config = load_skynet_toml()
key = load_key(config, 'skynet.user.key')
account = load_key(config, 'skynet.user.account')
permission = load_key(config, 'skynet.user.permission')
node_url = load_key(config, 'skynet.user.node_url')
logging.basicConfig(level=loglevel)
cleos = CLEOS(None, None, url=node_url, remote=node_url)
trio.run(
partial(
cleos.a_push_action,
'gpu.scd',
'clean',
{},
account, key, permission=permission
)
)
@skynet.command() @skynet.command()
def queue(): def queue():
import requests import requests
config = load_skynet_toml() config = load_skynet_toml()
node_url = load_key(config, 'skynet.user.node_url') node_url = config.user.node_url
resp = requests.post( resp = requests.post(
f'{node_url}/v1/chain/get_table_rows', f'{node_url}/v1/chain/get_table_rows',
json={ json={
@ -260,7 +155,7 @@ def queue():
def status(request_id: int): def status(request_id: int):
import requests import requests
config = load_skynet_toml() config = load_skynet_toml()
node_url = load_key(config, 'skynet.user.node_url') node_url = config.user.node_url
resp = requests.post( resp = requests.post(
f'{node_url}/v1/chain/get_table_rows', f'{node_url}/v1/chain/get_table_rows',
json={ json={
@ -272,101 +167,6 @@ def status(request_id: int):
) )
print(json.dumps(resp.json(), indent=4)) print(json.dumps(resp.json(), indent=4))
@skynet.command()
@click.argument('request-id')
def dequeue(request_id: int):
import trio
from leap.cleos import CLEOS
config = load_skynet_toml()
key = load_key(config, 'skynet.user.key')
account = load_key(config, 'skynet.user.account')
permission = load_key(config, 'skynet.user.permission')
node_url = load_key(config, 'skynet.user.node_url')
cleos = CLEOS(None, None, url=node_url, remote=node_url)
res = trio.run(
partial(
cleos.a_push_action,
'gpu.scd',
'dequeue',
{
'user': Name(account),
'request_id': int(request_id),
},
account, key, permission=permission
)
)
print(res)
@skynet.command()
@click.option(
'--token-contract', '-c', default='eosio.token')
@click.option(
'--token-symbol', '-S', default='4,GPU')
def config(
token_contract: str,
token_symbol: str
):
import trio
from leap.cleos import CLEOS
config = load_skynet_toml()
key = load_key(config, 'skynet.user.key')
account = load_key(config, 'skynet.user.account')
permission = load_key(config, 'skynet.user.permission')
node_url = load_key(config, 'skynet.user.node_url')
cleos = CLEOS(None, None, url=node_url, remote=node_url)
res = trio.run(
partial(
cleos.a_push_action,
'gpu.scd',
'config',
{
'token_contract': token_contract,
'token_symbol': token_symbol,
},
account, key, permission=permission
)
)
print(res)
@skynet.command()
@click.argument('quantity')
def deposit(quantity: str):
import trio
from leap.cleos import CLEOS
from leap.sugar import asset_from_str
config = load_skynet_toml()
key = load_key(config, 'skynet.user.key')
account = load_key(config, 'skynet.user.account')
permission = load_key(config, 'skynet.user.permission')
node_url = load_key(config, 'skynet.user.node_url')
cleos = CLEOS(None, None, url=node_url, remote=node_url)
res = trio.run(
partial(
cleos.a_push_action,
'gpu.scd',
'transfer',
{
'sender': Name(account),
'recipient': Name('gpu.scd'),
'amount': asset_from_str(quantity),
'memo': f'{account} transferred {quantity} to gpu.scd'
},
account, key, permission=permission
)
)
print(res)
@skynet.group() @skynet.group()
def run(*args, **kwargs): def run(*args, **kwargs):
pass pass
@ -380,13 +180,6 @@ def db():
container, passwd, host = db_params container, passwd, host = db_params
logging.info(('skynet', passwd, host)) logging.info(('skynet', passwd, host))
@run.command()
def nodeos():
from .nodeos import open_nodeos
logging.basicConfig(filename='skynet-nodeos.log', level=logging.INFO)
with open_nodeos(cleanup=False):
...
@run.command() @run.command()
@click.option('--loglevel', '-l', default='INFO', help='Logging level') @click.option('--loglevel', '-l', default='INFO', help='Logging level')
@ -405,14 +198,9 @@ def dgpu(
logging.basicConfig(level=loglevel) logging.basicConfig(level=loglevel)
config = load_skynet_toml(file_path=config_path) config = load_skynet_toml(file_path=config_path)
hf_token = load_key(config, 'skynet.dgpu.hf_token') set_hf_vars(config.dgpu.hf_token, config.dgpu.hf_home)
hf_home = load_key(config, 'skynet.dgpu.hf_home')
set_hf_vars(hf_token, hf_home)
assert 'skynet' in config trio.run(open_dgpu_node, config.dgpu)
assert 'dgpu' in config['skynet']
trio.run(open_dgpu_node, config['skynet']['dgpu'])
@run.command() @run.command()
@ -435,24 +223,24 @@ def telegram(
logging.basicConfig(level=loglevel) logging.basicConfig(level=loglevel)
config = load_skynet_toml() config = load_skynet_toml()
tg_token = load_key(config, 'skynet.telegram.tg_token') tg_token = config.telegram.tg_token
key = load_key(config, 'skynet.telegram.key') key = config.telegram.key
account = load_key(config, 'skynet.telegram.account') account = config.telegram.account
permission = load_key(config, 'skynet.telegram.permission') permission = config.telegram.permission
node_url = load_key(config, 'skynet.telegram.node_url') node_url = config.telegram.node_url
hyperion_url = load_key(config, 'skynet.telegram.hyperion_url') hyperion_url = config.telegram.hyperion_url
ipfs_url = load_key(config, 'skynet.telegram.ipfs_url') ipfs_url = config.telegram.ipfs_url
try: try:
explorer_domain = load_key(config, 'skynet.telegram.explorer_domain') explorer_domain = config.telegram.explorer_domain
except ConfigParsingError: except ConfigParsingError:
explorer_domain = DEFAULT_EXPLORER_DOMAIN explorer_domain = DEFAULT_EXPLORER_DOMAIN
try: try:
ipfs_domain = load_key(config, 'skynet.telegram.ipfs_domain') ipfs_domain = config.telegram.ipfs_domain
except ConfigParsingError: except ConfigParsingError:
ipfs_domain = DEFAULT_IPFS_DOMAIN ipfs_domain = DEFAULT_IPFS_DOMAIN
@ -498,24 +286,24 @@ def discord(
logging.basicConfig(level=loglevel) logging.basicConfig(level=loglevel)
config = load_skynet_toml() config = load_skynet_toml()
dc_token = load_key(config, 'skynet.discord.dc_token') dc_token = config.discord.dc_token
key = load_key(config, 'skynet.discord.key') key = config.discord.key
account = load_key(config, 'skynet.discord.account') account = config.discord.account
permission = load_key(config, 'skynet.discord.permission') permission = config.discord.permission
node_url = load_key(config, 'skynet.discord.node_url') node_url = config.discord.node_url
hyperion_url = load_key(config, 'skynet.discord.hyperion_url') hyperion_url = config.discord.hyperion_url
ipfs_url = load_key(config, 'skynet.discord.ipfs_url') ipfs_url = config.discord.ipfs_url
try: try:
explorer_domain = load_key(config, 'skynet.discord.explorer_domain') explorer_domain = config.discord.explorer_domain
except ConfigParsingError: except ConfigParsingError:
explorer_domain = DEFAULT_EXPLORER_DOMAIN explorer_domain = DEFAULT_EXPLORER_DOMAIN
try: try:
ipfs_domain = load_key(config, 'skynet.discord.ipfs_domain') ipfs_domain = config.discord.ipfs_domain
except ConfigParsingError: except ConfigParsingError:
ipfs_domain = DEFAULT_IPFS_DOMAIN ipfs_domain = DEFAULT_IPFS_DOMAIN
@ -549,8 +337,8 @@ def pinner(loglevel):
from .ipfs.pinner import SkynetPinner from .ipfs.pinner import SkynetPinner
config = load_skynet_toml() config = load_skynet_toml()
hyperion_url = load_key(config, 'skynet.pinner.hyperion_url') hyperion_url = config.pinner.hyperion_url
ipfs_url = load_key(config, 'skynet.pinner.ipfs_url') ipfs_url = config.pinner.ipfs_url
logging.basicConfig(level=loglevel) logging.basicConfig(level=loglevel)
ipfs_node = AsyncIPFSHTTP(ipfs_url) ipfs_node = AsyncIPFSHTTP(ipfs_url)

View File

@ -1,27 +1,70 @@
import os import os
import toml import toml
from .constants import DEFAULT_CONFIG_PATH import msgspec
from skynet.constants import DEFAULT_CONFIG_PATH, DEFAULT_IPFS_DOMAIN
class ConfigParsingError(BaseException): class ConfigParsingError(BaseException):
... ...
def load_skynet_toml(file_path=DEFAULT_CONFIG_PATH) -> dict: class DgpuConfig(msgspec.Struct):
config = toml.load(file_path) account: str
return config permission: str
key: str
node_url: str
hyperion_url: str
ipfs_url: str
hf_token: str
ipfs_domain: str = DEFAULT_IPFS_DOMAIN
hf_home: str = 'hf_home'
non_compete: set[str] = set()
model_whitelist: set[str] = set()
model_blacklist: set[str] = set()
backend: str = 'sync-on-thread'
api_bind: str = False
tui: bool = False
class TelegramConfig(msgspec.Struct):
account: str
permission: str
key: str
node_url: str
hyperion_url: str
ipfs_url: str
token: str
def load_key(config: dict, key: str) -> str: class DiscordConfig(msgspec.Struct):
for skey in key.split('.'): account: str
if skey not in config: permission: str
conf_keys = [k for k in config] key: str
raise ConfigParsingError(f'key \"{skey}\" not in {conf_keys}') node_url: str
hyperion_url: str
ipfs_url: str
token: str
config = config[skey] class PinnerConfig(msgspec.Struct):
hyperion_url: str
ipfs_url: str
return config class UserConfig(msgspec.Struct):
account: str
permission: str
key: str
node_url: str
class Config(msgspec.Struct):
dgpu: DgpuConfig | None = None
telegram: TelegramConfig | None = None
discord: DiscordConfig | None = None
pinner: PinnerConfig | None = None
user: UserConfig | None = None
def load_skynet_toml(file_path=DEFAULT_CONFIG_PATH) -> Config:
with open(file_path, 'r') as file:
return msgspec.toml.decode(file.read(), type=Config)
def set_hf_vars(hf_token: str, hf_home: str): def set_hf_vars(hf_token: str, hf_home: str):

View File

@ -3,16 +3,17 @@ import logging
import trio import trio
import urwid import urwid
from hypercorn.config import Config from hypercorn.config import Config as HCConfig
from hypercorn.trio import serve from hypercorn.trio import serve
from quart_trio import QuartTrio as Quart from quart_trio import QuartTrio as Quart
from skynet.config import Config
from skynet.dgpu.tui import init_tui from skynet.dgpu.tui import init_tui
from skynet.dgpu.daemon import WorkerDaemon from skynet.dgpu.daemon import WorkerDaemon
from skynet.dgpu.network import NetConnector from skynet.dgpu.network import NetConnector
async def open_dgpu_node(config: dict) -> None: async def open_dgpu_node(config: Config) -> None:
''' '''
Open a top level "GPU mgmt daemon", keep the Open a top level "GPU mgmt daemon", keep the
`WorkerDaemon._snap: dict[str, list|dict]` table `WorkerDaemon._snap: dict[str, list|dict]` table
@ -23,16 +24,16 @@ async def open_dgpu_node(config: dict) -> None:
logging.getLogger("httpx").setLevel(logging.WARNING) logging.getLogger("httpx").setLevel(logging.WARNING)
tui = None tui = None
if config['tui']: if config.tui:
tui = init_tui() tui = init_tui()
conn = NetConnector(config) conn = NetConnector(config)
daemon = WorkerDaemon(conn, config) daemon = WorkerDaemon(conn, config)
api: Quart|None = None api: Quart|None = None
if 'api_bind' in config: if config.api_bind:
api_conf = Config() api_conf = HCConfig()
api_conf.bind = [config['api_bind']] api_conf.bind = [config.api_bind]
api: Quart = await daemon.generate_api() api: Quart = await daemon.generate_api()
tn: trio.Nursery tn: trio.Nursery

View File

@ -10,6 +10,7 @@ import trio
from quart import jsonify from quart import jsonify
from quart_trio import QuartTrio as Quart from quart_trio import QuartTrio as Quart
from skynet.config import DgpuConfig as Config
from skynet.constants import ( from skynet.constants import (
MODELS, MODELS,
VERSION, VERSION,
@ -41,31 +42,10 @@ class WorkerDaemon:
def __init__( def __init__(
self, self,
conn: NetConnector, conn: NetConnector,
config: dict config: Config
): ):
self.config = config
self.conn: NetConnector = conn self.conn: NetConnector = conn
self.auto_withdraw = (
config['auto_withdraw']
if 'auto_withdraw' in config else False
)
self.account: str = config['account']
self.non_compete = set()
if 'non_compete' in config:
self.non_compete = set(config['non_compete'])
self.model_whitelist = set()
if 'model_whitelist' in config:
self.model_whitelist = set(config['model_whitelist'])
self.model_blacklist = set()
if 'model_blacklist' in config:
self.model_blacklist = set(config['model_blacklist'])
self.backend = 'sync-on-thread'
if 'backend' in config:
self.backend = config['backend']
self._snap = { self._snap = {
'queue': [], 'queue': [],
@ -107,10 +87,10 @@ class WorkerDaemon:
competitors = set([ competitors = set([
status['worker'] status['worker']
for status in self._snap['requests'][request_id] for status in self._snap['requests'][request_id]
if status['worker'] != self.account if status['worker'] != self.config.account
]) ])
logging.info(f'competitors: {competitors}') logging.info(f'competitors: {competitors}')
should_cancel = bool(self.non_compete & competitors) should_cancel = bool(self.config.non_compete & competitors)
logging.info(f'cancel: {should_cancel}') logging.info(f'cancel: {should_cancel}')
return should_cancel return should_cancel
@ -141,7 +121,7 @@ class WorkerDaemon:
@app.route('/') @app.route('/')
async def health(): async def health():
return jsonify( return jsonify(
account=self.account, account=self.config.account,
version=VERSION, version=VERSION,
last_generation_ts=self._last_generation_ts, last_generation_ts=self._last_generation_ts,
last_generation_speed=self._get_benchmark_speed() last_generation_speed=self._get_benchmark_speed()
@ -182,15 +162,19 @@ class WorkerDaemon:
# only handle whitelisted models # only handle whitelisted models
if ( if (
len(self.model_whitelist) > 0 len(self.config.model_whitelist) > 0
and and
model not in self.model_whitelist model not in self.config.model_whitelist
): ):
logging.warning('model not whitelisted!, skip...') logging.warning('model not whitelisted!, skip...')
return False return False
# if blacklist contains model skip # if blacklist contains model skip
if model in self.model_blacklist: if (
len(self.config.model_blacklist) > 0
and
model in self.config.model_blacklist
):
logging.warning('model not blacklisted!, skip...') logging.warning('model not blacklisted!, skip...')
return False return False
@ -205,7 +189,7 @@ class WorkerDaemon:
# skip if workers in non_compete already on it # skip if workers in non_compete already on it
competitors = set((status['worker'] for status in statuses)) competitors = set((status['worker'] for status in statuses))
if bool(self.non_compete & competitors): if bool(self.config.non_compete & competitors):
logging.info('worker in configured non_compete list already working on request, skip...') logging.info('worker in configured non_compete list already working on request, skip...')
return False return False
@ -266,7 +250,7 @@ class WorkerDaemon:
output = None output = None
output_hash = None output_hash = None
match self.backend: match self.config.backend:
case 'sync-on-thread': case 'sync-on-thread':
output_hash, output = await trio.to_thread.run_sync( output_hash, output = await trio.to_thread.run_sync(
partial( partial(
@ -280,7 +264,7 @@ class WorkerDaemon:
case _: case _:
raise DGPUComputeError( raise DGPUComputeError(
f'Unsupported backend {self.backend}' f'Unsupported backend {self.config.backend}'
) )
maybe_update_tui(lambda tui: tui.set_progress(total_step)) maybe_update_tui(lambda tui: tui.set_progress(total_step))
@ -316,9 +300,6 @@ class WorkerDaemon:
await self._update_balance() await self._update_balance()
try: try:
while True: while True:
if self.auto_withdraw:
await self.conn.maybe_withdraw_all()
queue = self._snap['queue'] queue = self._snap['queue']
random.shuffle(queue) random.shuffle(queue)

View File

@ -14,6 +14,7 @@ from PIL import Image
from leap.cleos import CLEOS from leap.cleos import CLEOS
from leap.protocol import Asset from leap.protocol import Asset
from skynet.dgpu.tui import maybe_update_tui from skynet.dgpu.tui import maybe_update_tui
from skynet.config import DgpuConfig as Config
from skynet.constants import ( from skynet.constants import (
DEFAULT_IPFS_DOMAIN, DEFAULT_IPFS_DOMAIN,
GPU_CONTRACT_ABI, GPU_CONTRACT_ABI,
@ -58,32 +59,16 @@ class NetConnector:
- CLEOS client - CLEOS client
''' '''
def __init__(self, config: dict): def __init__(self, config: Config):
# TODO, why these extra instance vars for an (unsynced) self.config = config
# copy of the `config` state? self.cleos = CLEOS(endpoint=config.node_url)
self.account = config['account']
self.permission = config['permission']
self.key = config['key']
# TODO, neither of these instance vars are used anywhere in
# methods? so why are they set on this type?
self.node_url = config['node_url']
self.hyperion_url = config['hyperion_url']
self.cleos = CLEOS(endpoint=self.node_url)
self.cleos.load_abi('gpu.scd', GPU_CONTRACT_ABI) self.cleos.load_abi('gpu.scd', GPU_CONTRACT_ABI)
self.ipfs_url = config['ipfs_url'] self.ipfs_client = AsyncIPFSHTTP(config.ipfs_url)
self.ipfs_client = AsyncIPFSHTTP(self.ipfs_url)
self.ipfs_domain = DEFAULT_IPFS_DOMAIN
if 'ipfs_domain' in config:
self.ipfs_domain = config['ipfs_domain']
self._wip_requests = {} self._wip_requests = {}
maybe_update_tui(lambda tui: tui.set_header_text(new_worker_name=self.account)) maybe_update_tui(lambda tui: tui.set_header_text(new_worker_name=self.config.account))
# blockchain helpers # blockchain helpers
@ -135,8 +120,8 @@ class NetConnector:
'gpu.scd', 'gpu.scd', 'users', 'gpu.scd', 'gpu.scd', 'users',
index_position=1, index_position=1,
key_type='name', key_type='name',
lower_bound=self.account, lower_bound=self.config.account,
upper_bound=self.account upper_bound=self.config.account
)) ))
if rows: if rows:
@ -190,12 +175,12 @@ class NetConnector:
'gpu.scd', 'gpu.scd',
'workbegin', 'workbegin',
list({ list({
'worker': self.account, 'worker': self.config.account,
'request_id': request_id, 'request_id': request_id,
'max_workers': 2 'max_workers': 2
}.values()), }.values()),
self.account, self.key, self.config.account, self.config.key,
permission=self.permission permission=self.config.permission
) )
) )
@ -207,12 +192,12 @@ class NetConnector:
'gpu.scd', 'gpu.scd',
'workcancel', 'workcancel',
list({ list({
'worker': self.account, 'worker': self.config.account,
'request_id': request_id, 'request_id': request_id,
'reason': reason 'reason': reason
}.values()), }.values()),
self.account, self.key, self.config.account, self.config.key,
permission=self.permission permission=self.config.permission
) )
) )
@ -230,11 +215,11 @@ class NetConnector:
'gpu.scd', 'gpu.scd',
'withdraw', 'withdraw',
list({ list({
'user': self.account, 'user': self.config.account,
'quantity': Asset.from_str(balance) 'quantity': Asset.from_str(balance)
}.values()), }.values()),
self.account, self.key, self.config.account, self.config.key,
permission=self.permission permission=self.config.permission
) )
) )
@ -246,8 +231,8 @@ class NetConnector:
'gpu.scd', 'gpu.scd', 'results', 'gpu.scd', 'gpu.scd', 'results',
index_position=4, index_position=4,
key_type='name', key_type='name',
lower_bound=self.account, lower_bound=self.config.account,
upper_bound=self.account upper_bound=self.config.account
) )
) )
return rows return rows
@ -266,14 +251,14 @@ class NetConnector:
'gpu.scd', 'gpu.scd',
'submit', 'submit',
list({ list({
'worker': self.account, 'worker': self.config.account,
'request_id': request_id, 'request_id': request_id,
'request_hash': request_hash, 'request_hash': request_hash,
'result_hash': result_hash, 'result_hash': result_hash,
'ipfs_hash': ipfs_hash 'ipfs_hash': ipfs_hash
}.values()), }.values()),
self.account, self.key, self.config.account, self.config.key,
permission=self.permission permission=self.config.permission
) )
) )
@ -310,7 +295,7 @@ class NetConnector:
consuming AI model. consuming AI model.
''' '''
link = f'https://{self.ipfs_domain}/ipfs/{ipfs_hash}' link = f'https://{self.config.ipfs_domain}/ipfs/{ipfs_hash}'
res = await get_ipfs_file(link, timeout=1) res = await get_ipfs_file(link, timeout=1)
if not res or res.status_code != 200: if not res or res.status_code != 200: