olas-operate-middleware 0.9.0__py3-none-any.whl → 0.10.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {olas_operate_middleware-0.9.0.dist-info → olas_operate_middleware-0.10.1.dist-info}/METADATA +1 -1
- {olas_operate_middleware-0.9.0.dist-info → olas_operate_middleware-0.10.1.dist-info}/RECORD +30 -30
- operate/bridge/bridge_manager.py +2 -3
- operate/bridge/providers/native_bridge_provider.py +1 -1
- operate/bridge/providers/provider.py +2 -3
- operate/bridge/providers/relay_provider.py +9 -1
- operate/cli.py +123 -43
- operate/constants.py +5 -0
- operate/keys.py +26 -14
- operate/ledger/profiles.py +1 -3
- operate/migration.py +288 -21
- operate/operate_types.py +9 -6
- operate/quickstart/analyse_logs.py +1 -4
- operate/quickstart/claim_staking_rewards.py +0 -3
- operate/quickstart/reset_configs.py +0 -3
- operate/quickstart/reset_password.py +0 -3
- operate/quickstart/reset_staking.py +2 -4
- operate/quickstart/run_service.py +3 -5
- operate/quickstart/stop_service.py +0 -3
- operate/quickstart/terminate_on_chain_service.py +0 -3
- operate/services/deployment_runner.py +170 -38
- operate/services/health_checker.py +3 -2
- operate/services/manage.py +90 -123
- operate/services/service.py +15 -225
- operate/utils/__init__.py +44 -0
- operate/utils/gnosis.py +22 -12
- operate/wallet/master.py +16 -20
- {olas_operate_middleware-0.9.0.dist-info → olas_operate_middleware-0.10.1.dist-info}/LICENSE +0 -0
- {olas_operate_middleware-0.9.0.dist-info → olas_operate_middleware-0.10.1.dist-info}/WHEEL +0 -0
- {olas_operate_middleware-0.9.0.dist-info → olas_operate_middleware-0.10.1.dist-info}/entry_points.txt +0 -0
operate/services/manage.py
CHANGED
|
@@ -23,7 +23,6 @@ import asyncio
|
|
|
23
23
|
import json
|
|
24
24
|
import logging
|
|
25
25
|
import os
|
|
26
|
-
import time
|
|
27
26
|
import traceback
|
|
28
27
|
import typing as t
|
|
29
28
|
from collections import Counter, defaultdict
|
|
@@ -34,8 +33,7 @@ from pathlib import Path
|
|
|
34
33
|
|
|
35
34
|
import requests
|
|
36
35
|
from aea.helpers.base import IPFSHash
|
|
37
|
-
from
|
|
38
|
-
from aea_ledger_ethereum import EthereumCrypto, LedgerApi
|
|
36
|
+
from aea_ledger_ethereum import LedgerApi
|
|
39
37
|
from autonomy.chain.base import registry_contracts
|
|
40
38
|
from autonomy.chain.config import CHAIN_PROFILES, ChainType
|
|
41
39
|
from autonomy.chain.metadata import IPFS_URI_PREFIX
|
|
@@ -47,7 +45,7 @@ from operate.data.contracts.requester_activity_checker.contract import (
|
|
|
47
45
|
RequesterActivityCheckerContract,
|
|
48
46
|
)
|
|
49
47
|
from operate.data.contracts.staking_token.contract import StakingTokenContract
|
|
50
|
-
from operate.keys import
|
|
48
|
+
from operate.keys import KeysManager
|
|
51
49
|
from operate.ledger import PUBLIC_RPCS, get_currency_denom
|
|
52
50
|
from operate.ledger.profiles import (
|
|
53
51
|
CONTRACTS,
|
|
@@ -76,6 +74,7 @@ from operate.services.service import (
|
|
|
76
74
|
NON_EXISTENT_TOKEN,
|
|
77
75
|
OnChainData,
|
|
78
76
|
SERVICE_CONFIG_PREFIX,
|
|
77
|
+
SERVICE_CONFIG_VERSION,
|
|
79
78
|
Service,
|
|
80
79
|
)
|
|
81
80
|
from operate.services.utils.mech import deploy_mech
|
|
@@ -98,9 +97,8 @@ class ServiceManager:
|
|
|
98
97
|
def __init__(
|
|
99
98
|
self,
|
|
100
99
|
path: Path,
|
|
101
|
-
keys_manager: KeysManager,
|
|
102
100
|
wallet_manager: MasterWalletManager,
|
|
103
|
-
logger:
|
|
101
|
+
logger: logging.Logger,
|
|
104
102
|
skip_dependency_check: t.Optional[bool] = False,
|
|
105
103
|
) -> None:
|
|
106
104
|
"""
|
|
@@ -112,43 +110,66 @@ class ServiceManager:
|
|
|
112
110
|
:param logger: logging.Logger object.
|
|
113
111
|
"""
|
|
114
112
|
self.path = path
|
|
115
|
-
self.keys_manager =
|
|
113
|
+
self.keys_manager = KeysManager()
|
|
116
114
|
self.wallet_manager = wallet_manager
|
|
117
|
-
self.logger = logger
|
|
115
|
+
self.logger = logger
|
|
118
116
|
self.skip_depencency_check = skip_dependency_check
|
|
119
117
|
|
|
120
118
|
def setup(self) -> None:
|
|
121
119
|
"""Setup service manager."""
|
|
122
120
|
self.path.mkdir(exist_ok=True)
|
|
123
121
|
|
|
124
|
-
def
|
|
122
|
+
def get_all_service_ids(self) -> t.List[str]:
|
|
123
|
+
"""
|
|
124
|
+
Get all service ids.
|
|
125
|
+
|
|
126
|
+
:return: List of service ids.
|
|
127
|
+
"""
|
|
128
|
+
return [
|
|
129
|
+
path.name
|
|
130
|
+
for path in self.path.iterdir()
|
|
131
|
+
if path.is_dir() and path.name.startswith(SERVICE_CONFIG_PREFIX)
|
|
132
|
+
]
|
|
133
|
+
|
|
134
|
+
def get_all_services(self) -> t.Tuple[t.List[Service], bool]:
|
|
135
|
+
"""Get all services."""
|
|
125
136
|
services = []
|
|
137
|
+
success = True
|
|
126
138
|
for path in self.path.iterdir():
|
|
127
139
|
if not path.name.startswith(SERVICE_CONFIG_PREFIX):
|
|
128
140
|
continue
|
|
129
141
|
try:
|
|
130
142
|
service = Service.load(path=path)
|
|
143
|
+
if service.version != SERVICE_CONFIG_VERSION:
|
|
144
|
+
self.logger.warning(
|
|
145
|
+
f"Service {path.name} has an unsupported version: {service.version}."
|
|
146
|
+
)
|
|
147
|
+
success = False
|
|
148
|
+
continue
|
|
149
|
+
|
|
131
150
|
services.append(service)
|
|
132
|
-
except ValueError as e:
|
|
133
|
-
raise e
|
|
134
151
|
except Exception as e: # pylint: disable=broad-except
|
|
135
152
|
self.logger.error(
|
|
136
153
|
f"Failed to load service: {path.name}. Exception {e}: {traceback.format_exc()}"
|
|
137
154
|
)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
os.rename(path, invalid_path)
|
|
142
|
-
self.logger.info(
|
|
143
|
-
f"Renamed invalid service: {path.name} to {invalid_path.name}"
|
|
144
|
-
)
|
|
155
|
+
success = False
|
|
156
|
+
|
|
157
|
+
return services, success
|
|
145
158
|
|
|
146
|
-
|
|
159
|
+
def validate_services(self) -> bool:
|
|
160
|
+
"""
|
|
161
|
+
Validate all services.
|
|
162
|
+
|
|
163
|
+
:return: True if all services are valid, False otherwise.
|
|
164
|
+
"""
|
|
165
|
+
_, success = self.get_all_services()
|
|
166
|
+
return success
|
|
147
167
|
|
|
148
168
|
@property
|
|
149
169
|
def json(self) -> t.List[t.Dict]:
|
|
150
170
|
"""Returns the list of available services."""
|
|
151
|
-
|
|
171
|
+
services, _ = self.get_all_services()
|
|
172
|
+
return [service.json for service in services]
|
|
152
173
|
|
|
153
174
|
def exists(self, service_config_id: str) -> bool:
|
|
154
175
|
"""Check if service exists."""
|
|
@@ -176,14 +197,14 @@ class ServiceManager:
|
|
|
176
197
|
self,
|
|
177
198
|
hash: str,
|
|
178
199
|
service_template: t.Optional[ServiceTemplate] = None,
|
|
179
|
-
|
|
200
|
+
agent_addresses: t.Optional[t.List[str]] = None,
|
|
180
201
|
) -> Service:
|
|
181
202
|
"""
|
|
182
203
|
Create or load a service
|
|
183
204
|
|
|
184
205
|
:param hash: Service hash
|
|
185
206
|
:param service_template: Service template
|
|
186
|
-
:param
|
|
207
|
+
:param agent_addresses: Agents' addresses to be used for the service.
|
|
187
208
|
:return: Service instance
|
|
188
209
|
"""
|
|
189
210
|
path = self.path / hash
|
|
@@ -202,21 +223,10 @@ class ServiceManager:
|
|
|
202
223
|
"'service_template' cannot be None when creating a new service"
|
|
203
224
|
)
|
|
204
225
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
storage=self.path,
|
|
208
|
-
service_template=service_template,
|
|
226
|
+
return self.create(
|
|
227
|
+
service_template=service_template, agent_addresses=agent_addresses
|
|
209
228
|
)
|
|
210
229
|
|
|
211
|
-
if not service.keys:
|
|
212
|
-
service.keys = [
|
|
213
|
-
self.keys_manager.get(self.keys_manager.create())
|
|
214
|
-
for _ in range(NUM_LOCAL_AGENT_INSTANCES)
|
|
215
|
-
]
|
|
216
|
-
service.store()
|
|
217
|
-
|
|
218
|
-
return service
|
|
219
|
-
|
|
220
230
|
def load(
|
|
221
231
|
self,
|
|
222
232
|
service_config_id: str,
|
|
@@ -233,25 +243,24 @@ class ServiceManager:
|
|
|
233
243
|
def create(
|
|
234
244
|
self,
|
|
235
245
|
service_template: ServiceTemplate,
|
|
236
|
-
|
|
246
|
+
agent_addresses: t.Optional[t.List[str]] = None,
|
|
237
247
|
) -> Service:
|
|
238
248
|
"""
|
|
239
249
|
Create a service
|
|
240
250
|
|
|
241
251
|
:param service_template: Service template
|
|
242
|
-
:param
|
|
252
|
+
:param agent_addresses: Agents' addresses to be used for the service.
|
|
243
253
|
:return: Service instance
|
|
244
254
|
"""
|
|
245
255
|
service = Service.new(
|
|
246
|
-
|
|
256
|
+
agent_addresses=agent_addresses or [],
|
|
247
257
|
storage=self.path,
|
|
248
258
|
service_template=service_template,
|
|
249
259
|
)
|
|
250
260
|
|
|
251
|
-
if not service.
|
|
252
|
-
service.
|
|
253
|
-
self.keys_manager.
|
|
254
|
-
for _ in range(NUM_LOCAL_AGENT_INSTANCES)
|
|
261
|
+
if not service.agent_addresses:
|
|
262
|
+
service.agent_addresses = [
|
|
263
|
+
self.keys_manager.create() for _ in range(NUM_LOCAL_AGENT_INSTANCES)
|
|
255
264
|
]
|
|
256
265
|
service.store()
|
|
257
266
|
|
|
@@ -314,8 +323,6 @@ class ServiceManager:
|
|
|
314
323
|
ledger_config = chain_config.ledger_config
|
|
315
324
|
chain_data = chain_config.chain_data
|
|
316
325
|
user_params = chain_config.chain_data.user_params
|
|
317
|
-
keys = service.keys
|
|
318
|
-
instances = [key.address for key in keys]
|
|
319
326
|
ocm = self.get_on_chain_manager(ledger_config=ledger_config)
|
|
320
327
|
|
|
321
328
|
# TODO fix this
|
|
@@ -427,7 +434,7 @@ class ServiceManager:
|
|
|
427
434
|
if user_params.use_staking
|
|
428
435
|
else user_params.cost_of_bond
|
|
429
436
|
),
|
|
430
|
-
threshold=
|
|
437
|
+
threshold=len(service.agent_addresses),
|
|
431
438
|
nft=IPFSHash(user_params.nft),
|
|
432
439
|
update_token=chain_data.token if is_update else None,
|
|
433
440
|
token=(
|
|
@@ -459,8 +466,8 @@ class ServiceManager:
|
|
|
459
466
|
agent_id = staking_params["agent_ids"][0]
|
|
460
467
|
ocm.register(
|
|
461
468
|
service_id=chain_data.token,
|
|
462
|
-
instances=
|
|
463
|
-
agents=[agent_id for _ in
|
|
469
|
+
instances=service.agent_addresses,
|
|
470
|
+
agents=[agent_id for _ in service.agent_addresses],
|
|
464
471
|
token=(OLAS[ledger_config.chain] if user_params.use_staking else None),
|
|
465
472
|
)
|
|
466
473
|
on_chain_state = OnChainState.FINISHED_REGISTRATION
|
|
@@ -610,8 +617,6 @@ class ServiceManager:
|
|
|
610
617
|
ledger_config = chain_config.ledger_config
|
|
611
618
|
chain_data = chain_config.chain_data
|
|
612
619
|
user_params = chain_config.chain_data.user_params
|
|
613
|
-
keys = service.keys
|
|
614
|
-
instances = [key.address for key in keys]
|
|
615
620
|
wallet = self.wallet_manager.load(ledger_config.chain.ledger_type)
|
|
616
621
|
sftxb = self.get_eth_safe_tx_builder(ledger_config=ledger_config)
|
|
617
622
|
safe = wallet.safes[Chain(chain)]
|
|
@@ -719,11 +724,14 @@ class ServiceManager:
|
|
|
719
724
|
}
|
|
720
725
|
)
|
|
721
726
|
|
|
722
|
-
#
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
+
# Set environment variables for the service
|
|
728
|
+
for dir_name, env_var_name in (
|
|
729
|
+
("persistent_data", "STORE_PATH"),
|
|
730
|
+
("benchmarks", "LOG_DIR"),
|
|
731
|
+
):
|
|
732
|
+
dir_path = service.path / dir_name
|
|
733
|
+
dir_path.mkdir(parents=True, exist_ok=True)
|
|
734
|
+
env_var_to_value.update({env_var_name: str(dir_path)})
|
|
727
735
|
|
|
728
736
|
service.update_env_variables_values(env_var_to_value)
|
|
729
737
|
|
|
@@ -834,7 +842,7 @@ class ServiceManager:
|
|
|
834
842
|
if user_params.use_staking
|
|
835
843
|
else user_params.cost_of_bond
|
|
836
844
|
),
|
|
837
|
-
threshold=
|
|
845
|
+
threshold=len(service.agent_addresses),
|
|
838
846
|
nft=IPFSHash(user_params.nft),
|
|
839
847
|
update_token=chain_data.token,
|
|
840
848
|
token=(
|
|
@@ -884,7 +892,7 @@ class ServiceManager:
|
|
|
884
892
|
if user_params.use_staking
|
|
885
893
|
else user_params.cost_of_bond
|
|
886
894
|
),
|
|
887
|
-
threshold=
|
|
895
|
+
threshold=len(service.agent_addresses),
|
|
888
896
|
nft=IPFSHash(user_params.nft),
|
|
889
897
|
update_token=None,
|
|
890
898
|
token=(
|
|
@@ -1013,10 +1021,10 @@ class ServiceManager:
|
|
|
1013
1021
|
self.logger.info(
|
|
1014
1022
|
f"Approved {token_utility_allowance} OLAS from {safe} to {token_utility}"
|
|
1015
1023
|
)
|
|
1016
|
-
cost_of_bond = 1 * len(
|
|
1024
|
+
cost_of_bond = 1 * len(service.agent_addresses)
|
|
1017
1025
|
|
|
1018
1026
|
self.logger.info(
|
|
1019
|
-
f"Registering agent instances: {chain_data.token} -> {
|
|
1027
|
+
f"Registering agent instances: {chain_data.token} -> {service.agent_addresses}"
|
|
1020
1028
|
)
|
|
1021
1029
|
|
|
1022
1030
|
native_balance = get_asset_balance(
|
|
@@ -1033,8 +1041,8 @@ class ServiceManager:
|
|
|
1033
1041
|
sftxb.new_tx().add(
|
|
1034
1042
|
sftxb.get_register_instances_data(
|
|
1035
1043
|
service_id=chain_data.token,
|
|
1036
|
-
instances=
|
|
1037
|
-
agents=[agent_id for _ in
|
|
1044
|
+
instances=service.agent_addresses,
|
|
1045
|
+
agents=[agent_id for _ in service.agent_addresses],
|
|
1038
1046
|
cost_of_bond=cost_of_bond,
|
|
1039
1047
|
)
|
|
1040
1048
|
).settle()
|
|
@@ -1179,8 +1187,6 @@ class ServiceManager:
|
|
|
1179
1187
|
chain_config = service.chain_configs[chain]
|
|
1180
1188
|
ledger_config = chain_config.ledger_config
|
|
1181
1189
|
chain_data = chain_config.chain_data
|
|
1182
|
-
keys = service.keys
|
|
1183
|
-
instances = [key.address for key in keys]
|
|
1184
1190
|
wallet = self.wallet_manager.load(ledger_config.chain.ledger_type)
|
|
1185
1191
|
safe = wallet.safes[Chain(chain)] # type: ignore
|
|
1186
1192
|
|
|
@@ -1245,7 +1251,7 @@ class ServiceManager:
|
|
|
1245
1251
|
# Swap service safe
|
|
1246
1252
|
current_safe_owners = sftxb.get_service_safe_owners(service_id=chain_data.token)
|
|
1247
1253
|
counter_current_safe_owners = Counter(s.lower() for s in current_safe_owners)
|
|
1248
|
-
counter_instances = Counter(s.lower() for s in
|
|
1254
|
+
counter_instances = Counter(s.lower() for s in service.agent_addresses)
|
|
1249
1255
|
|
|
1250
1256
|
if withdrawal_address is not None:
|
|
1251
1257
|
# we don't drain signer yet, because the owner swapping tx may need to happen
|
|
@@ -1290,16 +1296,15 @@ class ServiceManager:
|
|
|
1290
1296
|
) # noqa: E800
|
|
1291
1297
|
|
|
1292
1298
|
if withdrawal_address is not None:
|
|
1299
|
+
ethereum_crypto = KeysManager().get_crypto_instance(
|
|
1300
|
+
service.agent_addresses[0]
|
|
1301
|
+
)
|
|
1293
1302
|
# drain all native tokens from service signer key
|
|
1294
1303
|
drain_eoa(
|
|
1295
1304
|
ledger_api=self.wallet_manager.load(
|
|
1296
1305
|
ledger_config.chain.ledger_type
|
|
1297
1306
|
).ledger_api(chain=ledger_config.chain, rpc=ledger_config.rpc),
|
|
1298
|
-
crypto=
|
|
1299
|
-
private_key_path=service.path
|
|
1300
|
-
/ "deployment"
|
|
1301
|
-
/ "ethereum_private_key.txt",
|
|
1302
|
-
),
|
|
1307
|
+
crypto=ethereum_crypto,
|
|
1303
1308
|
withdrawal_address=withdrawal_address,
|
|
1304
1309
|
chain_id=ledger_config.chain.id,
|
|
1305
1310
|
)
|
|
@@ -1775,11 +1780,11 @@ class ServiceManager:
|
|
|
1775
1780
|
on_chain_state = self._get_on_chain_state(service=service, chain=chain)
|
|
1776
1781
|
if on_chain_state != OnChainState.DEPLOYED:
|
|
1777
1782
|
if chain_data.user_params.use_staking:
|
|
1778
|
-
on_chain_operations_buffer = 1 + len(service.
|
|
1783
|
+
on_chain_operations_buffer = 1 + len(service.agent_addresses)
|
|
1779
1784
|
else:
|
|
1780
1785
|
on_chain_operations_buffer = (
|
|
1781
1786
|
chain_data.user_params.cost_of_bond
|
|
1782
|
-
* (1 + len(service.
|
|
1787
|
+
* (1 + len(service.agent_addresses))
|
|
1783
1788
|
)
|
|
1784
1789
|
|
|
1785
1790
|
asset_funding_values = (
|
|
@@ -1793,21 +1798,21 @@ class ServiceManager:
|
|
|
1793
1798
|
else fund_requirements.agent
|
|
1794
1799
|
)
|
|
1795
1800
|
|
|
1796
|
-
for
|
|
1801
|
+
for agent_address in service.agent_addresses:
|
|
1797
1802
|
agent_balance = get_asset_balance(
|
|
1798
1803
|
ledger_api=ledger_api,
|
|
1799
1804
|
asset_address=asset_address,
|
|
1800
|
-
address=
|
|
1805
|
+
address=agent_address,
|
|
1801
1806
|
)
|
|
1802
1807
|
self.logger.info(
|
|
1803
|
-
f"[FUNDING_JOB] Agent {
|
|
1808
|
+
f"[FUNDING_JOB] Agent {agent_address} Asset: {asset_address} balance: {agent_balance}"
|
|
1804
1809
|
)
|
|
1805
1810
|
if agent_fund_threshold > 0:
|
|
1806
1811
|
self.logger.info(
|
|
1807
1812
|
f"[FUNDING_JOB] Required balance: {agent_fund_threshold}"
|
|
1808
1813
|
)
|
|
1809
1814
|
if agent_balance < agent_fund_threshold:
|
|
1810
|
-
self.logger.info(f"[FUNDING_JOB] Funding agent {
|
|
1815
|
+
self.logger.info(f"[FUNDING_JOB] Funding agent {agent_address}")
|
|
1811
1816
|
target_balance = (
|
|
1812
1817
|
asset_funding_values["agent"]["topup"]
|
|
1813
1818
|
if asset_funding_values is not None
|
|
@@ -1825,11 +1830,11 @@ class ServiceManager:
|
|
|
1825
1830
|
min(available_balance, target_balance - agent_balance), 0
|
|
1826
1831
|
)
|
|
1827
1832
|
self.logger.info(
|
|
1828
|
-
f"[FUNDING_JOB] Transferring {to_transfer} units (asset {asset_address}) to agent {
|
|
1833
|
+
f"[FUNDING_JOB] Transferring {to_transfer} units (asset {asset_address}) to agent {agent_address}"
|
|
1829
1834
|
)
|
|
1830
1835
|
wallet.transfer_asset(
|
|
1831
1836
|
asset=asset_address,
|
|
1832
|
-
to=
|
|
1837
|
+
to=agent_address,
|
|
1833
1838
|
amount=int(to_transfer),
|
|
1834
1839
|
chain=ledger_config.chain,
|
|
1835
1840
|
from_safe=from_safe,
|
|
@@ -1931,9 +1936,9 @@ class ServiceManager:
|
|
|
1931
1936
|
or chain_data.user_params.fund_requirements[ZERO_ADDRESS].agent
|
|
1932
1937
|
)
|
|
1933
1938
|
|
|
1934
|
-
for
|
|
1935
|
-
agent_balance = ledger_api.get_balance(address=
|
|
1936
|
-
self.logger.info(f"Agent {
|
|
1939
|
+
for agent_address in service.agent_addresses:
|
|
1940
|
+
agent_balance = ledger_api.get_balance(address=agent_address)
|
|
1941
|
+
self.logger.info(f"Agent {agent_address} balance: {agent_balance}")
|
|
1937
1942
|
self.logger.info(f"Required balance: {agent_fund_threshold}")
|
|
1938
1943
|
if agent_balance < agent_fund_threshold:
|
|
1939
1944
|
self.logger.info("Funding agents")
|
|
@@ -1941,10 +1946,10 @@ class ServiceManager:
|
|
|
1941
1946
|
agent_topup
|
|
1942
1947
|
or chain_data.user_params.fund_requirements[ZERO_ADDRESS].agent
|
|
1943
1948
|
)
|
|
1944
|
-
self.logger.info(f"Transferring {to_transfer} units to {
|
|
1949
|
+
self.logger.info(f"Transferring {to_transfer} units to {agent_address}")
|
|
1945
1950
|
wallet.transfer_erc20(
|
|
1946
1951
|
token=token,
|
|
1947
|
-
to=
|
|
1952
|
+
to=agent_address,
|
|
1948
1953
|
amount=int(to_transfer),
|
|
1949
1954
|
chain=ledger_config.chain,
|
|
1950
1955
|
from_safe=from_safe,
|
|
@@ -1979,7 +1984,7 @@ class ServiceManager:
|
|
|
1979
1984
|
rpc=rpc or ledger_config.rpc,
|
|
1980
1985
|
)
|
|
1981
1986
|
|
|
1982
|
-
def drain_service_safe(
|
|
1987
|
+
def drain_service_safe( # pylint: disable=too-many-locals
|
|
1983
1988
|
self,
|
|
1984
1989
|
service_config_id: str,
|
|
1985
1990
|
withdrawal_address: str,
|
|
@@ -1995,9 +2000,7 @@ class ServiceManager:
|
|
|
1995
2000
|
chain_data = chain_config.chain_data
|
|
1996
2001
|
wallet = self.wallet_manager.load(ledger_config.chain.ledger_type)
|
|
1997
2002
|
ledger_api = wallet.ledger_api(chain=ledger_config.chain, rpc=ledger_config.rpc)
|
|
1998
|
-
ethereum_crypto =
|
|
1999
|
-
private_key_path=service.path / "deployment" / "ethereum_private_key.txt",
|
|
2000
|
-
)
|
|
2003
|
+
ethereum_crypto = KeysManager().get_crypto_instance(service.agent_addresses[0])
|
|
2001
2004
|
|
|
2002
2005
|
# drain ERC20 tokens from service safe
|
|
2003
2006
|
for token_name, token_address in (
|
|
@@ -2171,40 +2174,6 @@ class ServiceManager:
|
|
|
2171
2174
|
)
|
|
2172
2175
|
return service
|
|
2173
2176
|
|
|
2174
|
-
def migrate_service_configs(self) -> None:
|
|
2175
|
-
"""Migrate old service config formats to new ones, if applies."""
|
|
2176
|
-
|
|
2177
|
-
bafybei_count = sum(
|
|
2178
|
-
1 for path in self.path.iterdir() if path.name.startswith("bafybei")
|
|
2179
|
-
)
|
|
2180
|
-
if bafybei_count > 1:
|
|
2181
|
-
self.log_directories()
|
|
2182
|
-
raise RuntimeError(
|
|
2183
|
-
f"Your services folder contains {bafybei_count} folders starting with 'bafybei'. This is an unintended situation. Please contact support."
|
|
2184
|
-
)
|
|
2185
|
-
|
|
2186
|
-
paths = list(self.path.iterdir())
|
|
2187
|
-
for path in paths:
|
|
2188
|
-
try:
|
|
2189
|
-
if path.name.startswith(SERVICE_CONFIG_PREFIX) or path.name.startswith(
|
|
2190
|
-
"bafybei"
|
|
2191
|
-
):
|
|
2192
|
-
self.logger.info(f"migrate_service_configs {str(path)}")
|
|
2193
|
-
migrated = Service.migrate_format(path)
|
|
2194
|
-
if migrated:
|
|
2195
|
-
self.logger.info(f"Folder {str(path)} has been migrated.")
|
|
2196
|
-
except Exception as e: # pylint: disable=broad-except
|
|
2197
|
-
self.logger.error(
|
|
2198
|
-
f"Failed to migrate service: {path.name}. Exception {e}: {traceback.format_exc()}"
|
|
2199
|
-
)
|
|
2200
|
-
# Rename the invalid path
|
|
2201
|
-
timestamp = int(time.time())
|
|
2202
|
-
invalid_path = path.parent / f"invalid_{timestamp}_{path.name}"
|
|
2203
|
-
os.rename(path, invalid_path)
|
|
2204
|
-
self.logger.info(
|
|
2205
|
-
f"Renamed invalid service: {path.name} to {invalid_path.name}"
|
|
2206
|
-
)
|
|
2207
|
-
|
|
2208
2177
|
def refill_requirements( # pylint: disable=too-many-locals,too-many-statements,too-many-nested-blocks
|
|
2209
2178
|
self, service_config_id: str
|
|
2210
2179
|
) -> t.Dict:
|
|
@@ -2232,11 +2201,9 @@ class ServiceManager:
|
|
|
2232
2201
|
master_safe_exists = wallet.safes.get(Chain(chain)) is not None
|
|
2233
2202
|
master_safe = wallet.safes.get(Chain(chain), "master_safe")
|
|
2234
2203
|
|
|
2235
|
-
agent_addresses =
|
|
2204
|
+
agent_addresses = set(service.agent_addresses)
|
|
2236
2205
|
service_safe = (
|
|
2237
|
-
chain_data.multisig
|
|
2238
|
-
if chain_data.multisig and chain_data.multisig != NON_EXISTENT_MULTISIG
|
|
2239
|
-
else "service_safe"
|
|
2206
|
+
chain_data.multisig if chain_data.multisig else "service_safe"
|
|
2240
2207
|
)
|
|
2241
2208
|
|
|
2242
2209
|
if not master_safe_exists:
|