olas-operate-middleware 0.6.3__py3-none-any.whl → 0.8.0__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.6.3.dist-info → olas_operate_middleware-0.8.0.dist-info}/METADATA +1 -1
- {olas_operate_middleware-0.6.3.dist-info → olas_operate_middleware-0.8.0.dist-info}/RECORD +21 -20
- operate/bridge/{bridge.py → bridge_manager.py} +99 -62
- operate/bridge/providers/{lifi_bridge_provider.py → lifi_provider.py} +94 -81
- operate/bridge/providers/native_bridge_provider.py +124 -115
- operate/bridge/providers/{bridge_provider.py → provider.py} +132 -150
- operate/bridge/providers/relay_provider.py +442 -0
- operate/cli.py +140 -110
- operate/constants.py +1 -0
- operate/ledger/profiles.py +11 -1
- operate/operate_types.py +10 -0
- operate/quickstart/claim_staking_rewards.py +1 -1
- operate/quickstart/reset_staking.py +1 -1
- operate/quickstart/run_service.py +34 -11
- operate/quickstart/terminate_on_chain_service.py +1 -1
- operate/quickstart/utils.py +0 -1
- operate/services/agent_runner.py +168 -91
- operate/services/manage.py +126 -72
- {olas_operate_middleware-0.6.3.dist-info → olas_operate_middleware-0.8.0.dist-info}/LICENSE +0 -0
- {olas_operate_middleware-0.6.3.dist-info → olas_operate_middleware-0.8.0.dist-info}/WHEEL +0 -0
- {olas_operate_middleware-0.6.3.dist-info → olas_operate_middleware-0.8.0.dist-info}/entry_points.txt +0 -0
|
@@ -24,7 +24,6 @@ import logging
|
|
|
24
24
|
import time
|
|
25
25
|
import typing as t
|
|
26
26
|
from abc import ABC, abstractmethod
|
|
27
|
-
from math import ceil
|
|
28
27
|
|
|
29
28
|
from aea.common import JSONLike
|
|
30
29
|
from aea.crypto.base import LedgerApi
|
|
@@ -32,15 +31,14 @@ from autonomy.chain.base import registry_contracts
|
|
|
32
31
|
from eth_typing import BlockIdentifier
|
|
33
32
|
from web3 import Web3
|
|
34
33
|
|
|
35
|
-
from operate.bridge.providers.
|
|
36
|
-
BridgeProvider,
|
|
37
|
-
BridgeRequest,
|
|
38
|
-
BridgeRequestStatus,
|
|
39
|
-
GAS_ESTIMATE_BUFFER,
|
|
34
|
+
from operate.bridge.providers.provider import (
|
|
40
35
|
MESSAGE_EXECUTION_FAILED,
|
|
41
36
|
MESSAGE_EXECUTION_FAILED_ETA,
|
|
42
37
|
MESSAGE_EXECUTION_FAILED_REVERTED,
|
|
43
38
|
MESSAGE_QUOTE_ZERO,
|
|
39
|
+
Provider,
|
|
40
|
+
ProviderRequest,
|
|
41
|
+
ProviderRequestStatus,
|
|
44
42
|
QuoteData,
|
|
45
43
|
)
|
|
46
44
|
from operate.constants import ZERO_ADDRESS
|
|
@@ -111,7 +109,7 @@ class BridgeContractAdaptor(ABC):
|
|
|
111
109
|
|
|
112
110
|
@abstractmethod
|
|
113
111
|
def build_bridge_tx(
|
|
114
|
-
self, from_ledger_api: LedgerApi,
|
|
112
|
+
self, from_ledger_api: LedgerApi, provider_request: ProviderRequest
|
|
115
113
|
) -> JSONLike:
|
|
116
114
|
"""Build bridge transaction."""
|
|
117
115
|
raise NotImplementedError()
|
|
@@ -121,7 +119,7 @@ class BridgeContractAdaptor(ABC):
|
|
|
121
119
|
self,
|
|
122
120
|
from_ledger_api: LedgerApi,
|
|
123
121
|
to_ledger_api: LedgerApi,
|
|
124
|
-
|
|
122
|
+
provider_request: ProviderRequest,
|
|
125
123
|
from_block: BlockIdentifier,
|
|
126
124
|
to_block: BlockIdentifier,
|
|
127
125
|
) -> t.Optional[str]:
|
|
@@ -130,7 +128,7 @@ class BridgeContractAdaptor(ABC):
|
|
|
130
128
|
|
|
131
129
|
@abstractmethod
|
|
132
130
|
def get_explorer_link(
|
|
133
|
-
self, from_ledger_api: LedgerApi,
|
|
131
|
+
self, from_ledger_api: LedgerApi, provider_request: ProviderRequest
|
|
134
132
|
) -> t.Optional[str]:
|
|
135
133
|
"""Get the explorer link for a transaction."""
|
|
136
134
|
raise NotImplementedError()
|
|
@@ -180,16 +178,16 @@ class OptimismContractAdaptor(BridgeContractAdaptor):
|
|
|
180
178
|
return super().can_handle_request(to_ledger_api, params)
|
|
181
179
|
|
|
182
180
|
def build_bridge_tx(
|
|
183
|
-
self, from_ledger_api: LedgerApi,
|
|
181
|
+
self, from_ledger_api: LedgerApi, provider_request: ProviderRequest
|
|
184
182
|
) -> JSONLike:
|
|
185
183
|
"""Build bridge transaction."""
|
|
186
|
-
from_address =
|
|
187
|
-
from_token =
|
|
188
|
-
to_address =
|
|
189
|
-
to_token =
|
|
190
|
-
to_amount =
|
|
184
|
+
from_address = provider_request.params["from"]["address"]
|
|
185
|
+
from_token = provider_request.params["from"]["token"]
|
|
186
|
+
to_address = provider_request.params["to"]["address"]
|
|
187
|
+
to_token = provider_request.params["to"]["token"]
|
|
188
|
+
to_amount = provider_request.params["to"]["amount"]
|
|
191
189
|
from_bridge = self.from_bridge
|
|
192
|
-
extra_data = Web3.keccak(text=
|
|
190
|
+
extra_data = Web3.keccak(text=provider_request.id)
|
|
193
191
|
|
|
194
192
|
if from_token == ZERO_ADDRESS:
|
|
195
193
|
return self._l1_standard_bridge_contract.build_bridge_eth_to_tx(
|
|
@@ -218,18 +216,18 @@ class OptimismContractAdaptor(BridgeContractAdaptor):
|
|
|
218
216
|
self,
|
|
219
217
|
from_ledger_api: LedgerApi,
|
|
220
218
|
to_ledger_api: LedgerApi,
|
|
221
|
-
|
|
219
|
+
provider_request: ProviderRequest,
|
|
222
220
|
from_block: BlockIdentifier,
|
|
223
221
|
to_block: BlockIdentifier,
|
|
224
222
|
) -> t.Optional[str]:
|
|
225
223
|
"""Return the transaction hash of the event indicating bridge completion."""
|
|
226
|
-
from_address =
|
|
227
|
-
from_token =
|
|
228
|
-
to_address =
|
|
229
|
-
to_token =
|
|
230
|
-
to_amount =
|
|
224
|
+
from_address = provider_request.params["from"]["address"]
|
|
225
|
+
from_token = provider_request.params["from"]["token"]
|
|
226
|
+
to_address = provider_request.params["to"]["address"]
|
|
227
|
+
to_token = provider_request.params["to"]["token"]
|
|
228
|
+
to_amount = provider_request.params["to"]["amount"]
|
|
231
229
|
to_bridge = self.to_bridge
|
|
232
|
-
extra_data = Web3.keccak(text=
|
|
230
|
+
extra_data = Web3.keccak(text=provider_request.id)
|
|
233
231
|
|
|
234
232
|
if from_token == ZERO_ADDRESS:
|
|
235
233
|
return self._l2_standard_bridge_contract.find_eth_bridge_finalized_tx(
|
|
@@ -257,17 +255,17 @@ class OptimismContractAdaptor(BridgeContractAdaptor):
|
|
|
257
255
|
)
|
|
258
256
|
|
|
259
257
|
def get_explorer_link(
|
|
260
|
-
self, from_ledger_api: LedgerApi,
|
|
258
|
+
self, from_ledger_api: LedgerApi, provider_request: ProviderRequest
|
|
261
259
|
) -> t.Optional[str]:
|
|
262
260
|
"""Get the explorer link for a transaction."""
|
|
263
|
-
if not
|
|
261
|
+
if not provider_request.execution_data:
|
|
264
262
|
return None
|
|
265
263
|
|
|
266
|
-
tx_hash =
|
|
264
|
+
tx_hash = provider_request.execution_data.from_tx_hash
|
|
267
265
|
if not tx_hash:
|
|
268
266
|
return None
|
|
269
267
|
|
|
270
|
-
chain = Chain(
|
|
268
|
+
chain = Chain(provider_request.params["from"]["chain"])
|
|
271
269
|
url = EXPLORER_URL[chain]["tx"]
|
|
272
270
|
return url.format(tx_hash=tx_hash)
|
|
273
271
|
|
|
@@ -298,13 +296,13 @@ class OmnibridgeContractAdaptor(BridgeContractAdaptor):
|
|
|
298
296
|
return super().can_handle_request(to_ledger_api, params)
|
|
299
297
|
|
|
300
298
|
def build_bridge_tx(
|
|
301
|
-
self, from_ledger_api: LedgerApi,
|
|
299
|
+
self, from_ledger_api: LedgerApi, provider_request: ProviderRequest
|
|
302
300
|
) -> JSONLike:
|
|
303
301
|
"""Build bridge transaction."""
|
|
304
|
-
from_address =
|
|
305
|
-
from_token =
|
|
306
|
-
to_address =
|
|
307
|
-
to_amount =
|
|
302
|
+
from_address = provider_request.params["from"]["address"]
|
|
303
|
+
from_token = provider_request.params["from"]["token"]
|
|
304
|
+
to_address = provider_request.params["to"]["address"]
|
|
305
|
+
to_amount = provider_request.params["to"]["amount"]
|
|
308
306
|
from_bridge = self.from_bridge
|
|
309
307
|
|
|
310
308
|
if from_token == ZERO_ADDRESS:
|
|
@@ -325,15 +323,15 @@ class OmnibridgeContractAdaptor(BridgeContractAdaptor):
|
|
|
325
323
|
self,
|
|
326
324
|
from_ledger_api: LedgerApi,
|
|
327
325
|
to_ledger_api: LedgerApi,
|
|
328
|
-
|
|
326
|
+
provider_request: ProviderRequest,
|
|
329
327
|
from_block: BlockIdentifier,
|
|
330
328
|
to_block: BlockIdentifier,
|
|
331
329
|
) -> t.Optional[str]:
|
|
332
330
|
"""Return the transaction hash of the event indicating bridge completion."""
|
|
333
|
-
from_token =
|
|
334
|
-
to_address =
|
|
335
|
-
to_token =
|
|
336
|
-
to_amount =
|
|
331
|
+
from_token = provider_request.params["from"]["token"]
|
|
332
|
+
to_address = provider_request.params["to"]["address"]
|
|
333
|
+
to_token = provider_request.params["to"]["token"]
|
|
334
|
+
to_amount = provider_request.params["to"]["amount"]
|
|
337
335
|
to_bridge = self.to_bridge
|
|
338
336
|
|
|
339
337
|
if from_token == ZERO_ADDRESS:
|
|
@@ -343,12 +341,12 @@ class OmnibridgeContractAdaptor(BridgeContractAdaptor):
|
|
|
343
341
|
|
|
344
342
|
message_id = self.get_message_id(
|
|
345
343
|
from_ledger_api=from_ledger_api,
|
|
346
|
-
|
|
344
|
+
provider_request=provider_request,
|
|
347
345
|
)
|
|
348
346
|
|
|
349
347
|
if not message_id:
|
|
350
348
|
raise RuntimeError(
|
|
351
|
-
f"Cannot find 'messageId' for
|
|
349
|
+
f"Cannot find 'messageId' for request {provider_request.id}."
|
|
352
350
|
)
|
|
353
351
|
|
|
354
352
|
return self._home_omnibridge.find_tokens_bridged_tx(
|
|
@@ -363,25 +361,25 @@ class OmnibridgeContractAdaptor(BridgeContractAdaptor):
|
|
|
363
361
|
)
|
|
364
362
|
|
|
365
363
|
def get_message_id(
|
|
366
|
-
self, from_ledger_api: LedgerApi,
|
|
364
|
+
self, from_ledger_api: LedgerApi, provider_request: ProviderRequest
|
|
367
365
|
) -> t.Optional[str]:
|
|
368
366
|
"""Get the bridge message id."""
|
|
369
|
-
if not
|
|
367
|
+
if not provider_request.execution_data:
|
|
370
368
|
return None
|
|
371
369
|
|
|
372
|
-
if not
|
|
370
|
+
if not provider_request.execution_data.from_tx_hash:
|
|
373
371
|
return None
|
|
374
372
|
|
|
375
373
|
if (
|
|
376
|
-
|
|
377
|
-
and "message_id" in
|
|
374
|
+
provider_request.execution_data.provider_data
|
|
375
|
+
and "message_id" in provider_request.execution_data.provider_data
|
|
378
376
|
):
|
|
379
|
-
return
|
|
377
|
+
return provider_request.execution_data.provider_data.get("message_id", None)
|
|
380
378
|
|
|
381
|
-
from_address =
|
|
382
|
-
from_token =
|
|
383
|
-
from_tx_hash =
|
|
384
|
-
to_amount =
|
|
379
|
+
from_address = provider_request.params["from"]["address"]
|
|
380
|
+
from_token = provider_request.params["from"]["token"]
|
|
381
|
+
from_tx_hash = provider_request.execution_data.from_tx_hash
|
|
382
|
+
to_amount = provider_request.params["to"]["amount"]
|
|
385
383
|
from_bridge = self.from_bridge
|
|
386
384
|
|
|
387
385
|
message_id = self._foreign_omnibridge.get_tokens_bridging_initiated_message_id(
|
|
@@ -393,17 +391,17 @@ class OmnibridgeContractAdaptor(BridgeContractAdaptor):
|
|
|
393
391
|
value=to_amount,
|
|
394
392
|
)
|
|
395
393
|
|
|
396
|
-
if not
|
|
397
|
-
|
|
394
|
+
if not provider_request.execution_data.provider_data:
|
|
395
|
+
provider_request.execution_data.provider_data = {}
|
|
398
396
|
|
|
399
|
-
|
|
397
|
+
provider_request.execution_data.provider_data["message_id"] = message_id
|
|
400
398
|
return message_id
|
|
401
399
|
|
|
402
400
|
def get_explorer_link(
|
|
403
|
-
self, from_ledger_api: LedgerApi,
|
|
401
|
+
self, from_ledger_api: LedgerApi, provider_request: ProviderRequest
|
|
404
402
|
) -> t.Optional[str]:
|
|
405
403
|
"""Get the explorer link for a transaction."""
|
|
406
|
-
message_id = self.get_message_id(from_ledger_api,
|
|
404
|
+
message_id = self.get_message_id(from_ledger_api, provider_request)
|
|
407
405
|
if not message_id:
|
|
408
406
|
return None
|
|
409
407
|
return (
|
|
@@ -411,7 +409,7 @@ class OmnibridgeContractAdaptor(BridgeContractAdaptor):
|
|
|
411
409
|
)
|
|
412
410
|
|
|
413
411
|
|
|
414
|
-
class NativeBridgeProvider(
|
|
412
|
+
class NativeBridgeProvider(Provider):
|
|
415
413
|
"""Native bridge provider"""
|
|
416
414
|
|
|
417
415
|
def __init__(
|
|
@@ -421,14 +419,14 @@ class NativeBridgeProvider(BridgeProvider):
|
|
|
421
419
|
wallet_manager: MasterWalletManager,
|
|
422
420
|
logger: t.Optional[logging.Logger] = None,
|
|
423
421
|
) -> None:
|
|
424
|
-
"""Initialize the
|
|
422
|
+
"""Initialize the provider."""
|
|
425
423
|
self.bridge_contract_adaptor = bridge_contract_adaptor
|
|
426
424
|
super().__init__(
|
|
427
425
|
wallet_manager=wallet_manager, provider_id=provider_id, logger=logger
|
|
428
426
|
)
|
|
429
427
|
|
|
430
428
|
def can_handle_request(self, params: t.Dict) -> bool:
|
|
431
|
-
"""Returns 'true' if the
|
|
429
|
+
"""Returns 'true' if the provider can handle a request for 'params'."""
|
|
432
430
|
|
|
433
431
|
if not super().can_handle_request(params):
|
|
434
432
|
return False
|
|
@@ -444,64 +442,64 @@ class NativeBridgeProvider(BridgeProvider):
|
|
|
444
442
|
return True
|
|
445
443
|
|
|
446
444
|
def description(self) -> str:
|
|
447
|
-
"""Get a human-readable description of the
|
|
445
|
+
"""Get a human-readable description of the provider."""
|
|
448
446
|
return f"Native bridge provider ({self.bridge_contract_adaptor.__class__.__name__})."
|
|
449
447
|
|
|
450
|
-
def quote(self,
|
|
448
|
+
def quote(self, provider_request: ProviderRequest) -> None:
|
|
451
449
|
"""Update the request with the quote."""
|
|
452
|
-
self._validate(
|
|
450
|
+
self._validate(provider_request)
|
|
453
451
|
|
|
454
|
-
if
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
452
|
+
if provider_request.status not in (
|
|
453
|
+
ProviderRequestStatus.CREATED,
|
|
454
|
+
ProviderRequestStatus.QUOTE_DONE,
|
|
455
|
+
ProviderRequestStatus.QUOTE_FAILED,
|
|
458
456
|
):
|
|
459
457
|
raise RuntimeError(
|
|
460
|
-
f"Cannot quote
|
|
458
|
+
f"Cannot quote request {provider_request.id} with status {provider_request.status}."
|
|
461
459
|
)
|
|
462
460
|
|
|
463
|
-
if
|
|
461
|
+
if provider_request.execution_data:
|
|
464
462
|
raise RuntimeError(
|
|
465
|
-
f"Cannot quote
|
|
463
|
+
f"Cannot quote request {provider_request.id}: execution already present."
|
|
466
464
|
)
|
|
467
465
|
|
|
468
|
-
to_amount =
|
|
466
|
+
to_amount = provider_request.params["to"]["amount"]
|
|
469
467
|
bridge_eta = self.bridge_contract_adaptor.bridge_eta
|
|
470
468
|
|
|
471
469
|
message = None
|
|
472
470
|
if to_amount == 0:
|
|
473
|
-
self.logger.info(f"[NATIVE BRIDGE] {MESSAGE_QUOTE_ZERO}")
|
|
471
|
+
self.logger.info(f"[NATIVE BRIDGE PROVIDER] {MESSAGE_QUOTE_ZERO}")
|
|
474
472
|
bridge_eta = 0
|
|
475
473
|
message = MESSAGE_QUOTE_ZERO
|
|
476
474
|
|
|
477
475
|
quote_data = QuoteData(
|
|
478
|
-
|
|
476
|
+
eta=bridge_eta,
|
|
479
477
|
elapsed_time=0,
|
|
480
478
|
message=message,
|
|
481
479
|
provider_data=None,
|
|
482
480
|
timestamp=int(time.time()),
|
|
483
481
|
)
|
|
484
|
-
|
|
485
|
-
|
|
482
|
+
provider_request.quote_data = quote_data
|
|
483
|
+
provider_request.status = ProviderRequestStatus.QUOTE_DONE
|
|
486
484
|
|
|
487
|
-
def _get_approve_tx(self,
|
|
485
|
+
def _get_approve_tx(self, provider_request: ProviderRequest) -> t.Optional[t.Dict]:
|
|
488
486
|
"""Get the approve transaction."""
|
|
489
487
|
self.logger.info(
|
|
490
|
-
f"[NATIVE BRIDGE] Get appprove transaction for
|
|
488
|
+
f"[NATIVE BRIDGE PROVIDER] Get appprove transaction for request {provider_request.id}."
|
|
491
489
|
)
|
|
492
490
|
|
|
493
|
-
if
|
|
491
|
+
if provider_request.params["to"]["amount"] == 0:
|
|
494
492
|
return None
|
|
495
493
|
|
|
496
|
-
quote_data =
|
|
494
|
+
quote_data = provider_request.quote_data
|
|
497
495
|
if not quote_data:
|
|
498
496
|
return None
|
|
499
497
|
|
|
500
|
-
from_address =
|
|
501
|
-
from_token =
|
|
502
|
-
to_amount =
|
|
498
|
+
from_address = provider_request.params["from"]["address"]
|
|
499
|
+
from_token = provider_request.params["from"]["token"]
|
|
500
|
+
to_amount = provider_request.params["to"]["amount"]
|
|
503
501
|
from_bridge = self.bridge_contract_adaptor.from_bridge
|
|
504
|
-
from_ledger_api = self._from_ledger_api(
|
|
502
|
+
from_ledger_api = self._from_ledger_api(provider_request)
|
|
505
503
|
|
|
506
504
|
if from_token == ZERO_ADDRESS:
|
|
507
505
|
return None
|
|
@@ -514,68 +512,79 @@ class NativeBridgeProvider(BridgeProvider):
|
|
|
514
512
|
amount=to_amount,
|
|
515
513
|
)
|
|
516
514
|
approve_tx["gas"] = 200_000 # TODO backport to ERC20 contract as default
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
approve_tx["gas"] = ceil(approve_tx["gas"] * GAS_ESTIMATE_BUFFER)
|
|
515
|
+
Provider._update_with_gas_pricing(approve_tx, from_ledger_api)
|
|
516
|
+
Provider._update_with_gas_estimate(approve_tx, from_ledger_api)
|
|
520
517
|
return approve_tx
|
|
521
518
|
|
|
522
|
-
def _get_bridge_tx(self,
|
|
519
|
+
def _get_bridge_tx(self, provider_request: ProviderRequest) -> t.Optional[t.Dict]:
|
|
523
520
|
"""Get the bridge transaction."""
|
|
524
521
|
self.logger.info(
|
|
525
|
-
f"[NATIVE BRIDGE] Get bridge transaction for
|
|
522
|
+
f"[NATIVE BRIDGE PROVIDER] Get bridge transaction for request {provider_request.id}."
|
|
526
523
|
)
|
|
527
524
|
|
|
528
|
-
if
|
|
525
|
+
if provider_request.params["to"]["amount"] == 0:
|
|
529
526
|
return None
|
|
530
527
|
|
|
531
|
-
quote_data =
|
|
528
|
+
quote_data = provider_request.quote_data
|
|
532
529
|
if not quote_data:
|
|
533
530
|
return None
|
|
534
531
|
|
|
535
|
-
from_ledger_api = self._from_ledger_api(
|
|
532
|
+
from_ledger_api = self._from_ledger_api(provider_request)
|
|
536
533
|
bridge_tx = self.bridge_contract_adaptor.build_bridge_tx(
|
|
537
|
-
from_ledger_api=from_ledger_api,
|
|
534
|
+
from_ledger_api=from_ledger_api, provider_request=provider_request
|
|
538
535
|
)
|
|
539
536
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
bridge_tx["gas"] = ceil(bridge_tx["gas"] * GAS_ESTIMATE_BUFFER)
|
|
537
|
+
Provider._update_with_gas_pricing(bridge_tx, from_ledger_api)
|
|
538
|
+
Provider._update_with_gas_estimate(bridge_tx, from_ledger_api)
|
|
543
539
|
return bridge_tx
|
|
544
540
|
|
|
545
|
-
def
|
|
541
|
+
def _get_txs(
|
|
542
|
+
self, provider_request: ProviderRequest, *args: t.Any, **kwargs: t.Any
|
|
543
|
+
) -> t.List[t.Tuple[str, t.Dict]]:
|
|
544
|
+
"""Get the sorted list of transactions to execute the quote."""
|
|
545
|
+
txs = []
|
|
546
|
+
approve_tx = self._get_approve_tx(provider_request)
|
|
547
|
+
if approve_tx:
|
|
548
|
+
txs.append(("approve_tx", approve_tx))
|
|
549
|
+
bridge_tx = self._get_bridge_tx(provider_request)
|
|
550
|
+
if bridge_tx:
|
|
551
|
+
txs.append(("bridge_tx", bridge_tx))
|
|
552
|
+
return txs
|
|
553
|
+
|
|
554
|
+
def _update_execution_status(self, provider_request: ProviderRequest) -> None:
|
|
546
555
|
"""Update the execution status."""
|
|
547
556
|
|
|
548
|
-
if
|
|
557
|
+
if provider_request.status != ProviderRequestStatus.EXECUTION_PENDING:
|
|
549
558
|
return
|
|
550
559
|
|
|
551
560
|
self.logger.info(
|
|
552
|
-
f"[NATIVE BRIDGE] Updating execution status for
|
|
561
|
+
f"[NATIVE BRIDGE PROVIDER] Updating execution status for request {provider_request.id}."
|
|
553
562
|
)
|
|
554
563
|
|
|
555
|
-
|
|
564
|
+
execution_data = provider_request.execution_data
|
|
565
|
+
if not execution_data:
|
|
556
566
|
raise RuntimeError(
|
|
557
|
-
f"Cannot update
|
|
567
|
+
f"Cannot update {provider_request.id}: execution data not present."
|
|
558
568
|
)
|
|
559
569
|
|
|
560
|
-
|
|
561
|
-
if not
|
|
570
|
+
from_tx_hash = execution_data.from_tx_hash
|
|
571
|
+
if not from_tx_hash:
|
|
562
572
|
execution_data.message = (
|
|
563
573
|
f"{MESSAGE_EXECUTION_FAILED} missing transaction hash."
|
|
564
574
|
)
|
|
565
|
-
|
|
575
|
+
provider_request.status = ProviderRequestStatus.EXECUTION_FAILED
|
|
566
576
|
return
|
|
567
577
|
|
|
568
578
|
bridge_eta = self.bridge_contract_adaptor.bridge_eta
|
|
569
579
|
|
|
570
580
|
try:
|
|
571
|
-
from_ledger_api = self._from_ledger_api(
|
|
581
|
+
from_ledger_api = self._from_ledger_api(provider_request)
|
|
572
582
|
from_w3 = from_ledger_api.api
|
|
573
583
|
|
|
574
|
-
from_tx_hash = execution_data.from_tx_hash
|
|
575
584
|
receipt = from_w3.eth.get_transaction_receipt(from_tx_hash)
|
|
576
585
|
if receipt.status == 0:
|
|
577
586
|
execution_data.message = MESSAGE_EXECUTION_FAILED_REVERTED
|
|
578
|
-
|
|
587
|
+
provider_request.status = ProviderRequestStatus.EXECUTION_FAILED
|
|
579
588
|
return
|
|
580
589
|
|
|
581
590
|
# Get the timestamp of the bridge_tx on the 'from' chain
|
|
@@ -584,7 +593,7 @@ class NativeBridgeProvider(BridgeProvider):
|
|
|
584
593
|
bridge_tx_ts = bridge_tx_block.timestamp
|
|
585
594
|
|
|
586
595
|
# Find the event on the 'to' chain
|
|
587
|
-
to_ledger_api = self._to_ledger_api(
|
|
596
|
+
to_ledger_api = self._to_ledger_api(provider_request)
|
|
588
597
|
to_w3 = to_ledger_api.api
|
|
589
598
|
starting_block = self._find_block_before_timestamp(to_w3, bridge_tx_ts)
|
|
590
599
|
starting_block_ts = to_w3.eth.get_block(starting_block).timestamp
|
|
@@ -596,30 +605,30 @@ class NativeBridgeProvider(BridgeProvider):
|
|
|
596
605
|
to_tx_hash = self.bridge_contract_adaptor.find_bridge_finalized_tx(
|
|
597
606
|
from_ledger_api=from_ledger_api,
|
|
598
607
|
to_ledger_api=to_ledger_api,
|
|
599
|
-
|
|
608
|
+
provider_request=provider_request,
|
|
600
609
|
from_block=from_block,
|
|
601
610
|
to_block=to_block,
|
|
602
611
|
)
|
|
603
612
|
|
|
604
613
|
if to_tx_hash:
|
|
605
614
|
self.logger.info(
|
|
606
|
-
f"[NATIVE BRIDGE] Execution done for {
|
|
615
|
+
f"[NATIVE BRIDGE PROVIDER] Execution done for request {provider_request.id}."
|
|
607
616
|
)
|
|
608
617
|
execution_data.message = None
|
|
609
618
|
execution_data.to_tx_hash = to_tx_hash
|
|
610
|
-
execution_data.elapsed_time =
|
|
619
|
+
execution_data.elapsed_time = Provider._tx_timestamp(
|
|
611
620
|
to_tx_hash, to_ledger_api
|
|
612
|
-
) -
|
|
613
|
-
|
|
621
|
+
) - Provider._tx_timestamp(from_tx_hash, from_ledger_api)
|
|
622
|
+
provider_request.status = ProviderRequestStatus.EXECUTION_DONE
|
|
614
623
|
return
|
|
615
624
|
|
|
616
625
|
last_block_ts = to_w3.eth.get_block(to_block).timestamp
|
|
617
626
|
if last_block_ts > starting_block_ts + bridge_eta * 2:
|
|
618
627
|
self.logger.info(
|
|
619
|
-
f"[NATIVE BRIDGE] Execution failed for {
|
|
628
|
+
f"[NATIVE BRIDGE PROVIDER] Execution failed for request {provider_request.id}: bridge exceeds 2*ETA."
|
|
620
629
|
)
|
|
621
630
|
execution_data.message = MESSAGE_EXECUTION_FAILED_ETA
|
|
622
|
-
|
|
631
|
+
provider_request.status = ProviderRequestStatus.EXECUTION_FAILED
|
|
623
632
|
return
|
|
624
633
|
|
|
625
634
|
except Exception as e:
|
|
@@ -628,7 +637,7 @@ class NativeBridgeProvider(BridgeProvider):
|
|
|
628
637
|
|
|
629
638
|
traceback.print_exc()
|
|
630
639
|
execution_data.message = f"{MESSAGE_EXECUTION_FAILED} {str(e)}"
|
|
631
|
-
|
|
640
|
+
provider_request.status = ProviderRequestStatus.EXECUTION_FAILED
|
|
632
641
|
|
|
633
642
|
@staticmethod
|
|
634
643
|
def _find_block_before_timestamp(w3: Web3, timestamp: int) -> int:
|
|
@@ -646,9 +655,9 @@ class NativeBridgeProvider(BridgeProvider):
|
|
|
646
655
|
high = mid - 1
|
|
647
656
|
return best
|
|
648
657
|
|
|
649
|
-
def _get_explorer_link(self,
|
|
658
|
+
def _get_explorer_link(self, provider_request: ProviderRequest) -> t.Optional[str]:
|
|
650
659
|
"""Get the explorer link for a transaction."""
|
|
651
|
-
from_ledger_api = self._from_ledger_api(
|
|
660
|
+
from_ledger_api = self._from_ledger_api(provider_request)
|
|
652
661
|
return self.bridge_contract_adaptor.get_explorer_link(
|
|
653
|
-
from_ledger_api=from_ledger_api,
|
|
662
|
+
from_ledger_api=from_ledger_api, provider_request=provider_request
|
|
654
663
|
)
|