Skip to content

Commit 70d13fb

Browse files
committed
[Experimental] Improve submit_extrinsic util
1 parent aac3e1a commit 70d13fb

File tree

9 files changed

+58
-43
lines changed

9 files changed

+58
-43
lines changed

bittensor/core/extrinsics/commit_weights.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def do_commit_weights(
7171
keypair=wallet.hotkey,
7272
)
7373
response = submit_extrinsic(
74-
substrate=self.substrate,
74+
subtensor=self,
7575
extrinsic=extrinsic,
7676
wait_for_inclusion=wait_for_inclusion,
7777
wait_for_finalization=wait_for_finalization,
@@ -184,7 +184,7 @@ def do_reveal_weights(
184184
keypair=wallet.hotkey,
185185
)
186186
response = submit_extrinsic(
187-
substrate=self.substrate,
187+
subtensor=self,
188188
extrinsic=extrinsic,
189189
wait_for_inclusion=wait_for_inclusion,
190190
wait_for_finalization=wait_for_finalization,

bittensor/core/extrinsics/registration.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def _do_pow_register(
6666
)
6767
extrinsic = self.substrate.create_signed_extrinsic(call=call, keypair=wallet.hotkey)
6868
response = submit_extrinsic(
69-
substrate=self.substrate,
69+
self,
7070
extrinsic=extrinsic,
7171
wait_for_inclusion=wait_for_inclusion,
7272
wait_for_finalization=wait_for_finalization,
@@ -297,7 +297,7 @@ def _do_burned_register(
297297
call=call, keypair=wallet.coldkey
298298
)
299299
response = submit_extrinsic(
300-
self.substrate,
300+
self,
301301
extrinsic,
302302
wait_for_inclusion=wait_for_inclusion,
303303
wait_for_finalization=wait_for_finalization,

bittensor/core/extrinsics/root.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def _do_root_register(
3333
call=call, keypair=wallet.coldkey
3434
)
3535
response = submit_extrinsic(
36-
self.substrate,
36+
self,
3737
extrinsic,
3838
wait_for_inclusion=wait_for_inclusion,
3939
wait_for_finalization=wait_for_finalization,
@@ -159,7 +159,7 @@ def _do_set_root_weights(
159159
era={"period": period},
160160
)
161161
response = submit_extrinsic(
162-
self.substrate,
162+
self,
163163
extrinsic,
164164
wait_for_inclusion=wait_for_inclusion,
165165
wait_for_finalization=wait_for_finalization,

bittensor/core/extrinsics/serving.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def do_serve_axon(
7575
)
7676
extrinsic = self.substrate.create_signed_extrinsic(call=call, keypair=wallet.hotkey)
7777
response = submit_extrinsic(
78-
substrate=self.substrate,
78+
self,
7979
extrinsic=extrinsic,
8080
wait_for_inclusion=wait_for_inclusion,
8181
wait_for_finalization=wait_for_finalization,
@@ -289,7 +289,7 @@ def publish_metadata(
289289

290290
extrinsic = substrate.create_signed_extrinsic(call=call, keypair=wallet.hotkey)
291291
response = submit_extrinsic(
292-
substrate,
292+
self,
293293
extrinsic,
294294
wait_for_inclusion=wait_for_inclusion,
295295
wait_for_finalization=wait_for_finalization,

bittensor/core/extrinsics/set_weights.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def do_set_weights(
8383
era={"period": period},
8484
)
8585
response = submit_extrinsic(
86-
substrate=self.substrate,
86+
self,
8787
extrinsic=extrinsic,
8888
wait_for_inclusion=wait_for_inclusion,
8989
wait_for_finalization=wait_for_finalization,

bittensor/core/extrinsics/transfer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def do_transfer(
7070
call=call, keypair=wallet.coldkey
7171
)
7272
response = submit_extrinsic(
73-
substrate=self.substrate,
73+
self,
7474
extrinsic=extrinsic,
7575
wait_for_inclusion=wait_for_inclusion,
7676
wait_for_finalization=wait_for_finalization,

bittensor/core/extrinsics/utils.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
from bittensor.utils import format_error_message
1212

1313
if TYPE_CHECKING:
14-
from substrateinterface import SubstrateInterface, ExtrinsicReceipt
14+
from bittensor.core.subtensor import Subtensor
15+
from substrateinterface import ExtrinsicReceipt
1516
from scalecodec.types import GenericExtrinsic
1617

1718
try:
@@ -26,7 +27,7 @@
2627

2728

2829
def submit_extrinsic(
29-
substrate: "SubstrateInterface",
30+
subtensor: "Subtensor",
3031
extrinsic: "GenericExtrinsic",
3132
wait_for_inclusion: bool,
3233
wait_for_finalization: bool,
@@ -39,7 +40,7 @@ def submit_extrinsic(
3940
it logs the error and re-raises the exception.
4041
4142
Args:
42-
substrate (substrateinterface.SubstrateInterface): The substrate interface instance used to interact with the blockchain.
43+
subtensor: The Subtensor instance used to interact with the blockchain.
4344
extrinsic (scalecodec.types.GenericExtrinsic): The extrinsic to be submitted to the blockchain.
4445
wait_for_inclusion (bool): Whether to wait for the extrinsic to be included in a block.
4546
wait_for_finalization (bool): Whether to wait for the extrinsic to be finalized on the blockchain.
@@ -51,20 +52,22 @@ def submit_extrinsic(
5152
SubstrateRequestException: If the submission of the extrinsic fails, the error is logged and re-raised.
5253
"""
5354
extrinsic_hash = extrinsic.extrinsic_hash
54-
starting_block = substrate.get_block()
55+
starting_block = subtensor.substrate.get_block()
5556

5657
timeout = EXTRINSIC_SUBMISSION_TIMEOUT
5758
event = threading.Event()
5859

5960
def submit():
6061
try:
61-
response_ = substrate.submit_extrinsic(
62+
response_ = subtensor.substrate.submit_extrinsic(
6263
extrinsic,
6364
wait_for_inclusion=wait_for_inclusion,
6465
wait_for_finalization=wait_for_finalization,
6566
)
6667
except SubstrateRequestException as e:
67-
logging.error(format_error_message(e.args[0], substrate=substrate))
68+
logging.error(
69+
format_error_message(e.args[0], substrate=subtensor.substrate)
70+
)
6871
# Re-raise the exception for retrying of the extrinsic call. If we remove the retry logic,
6972
# the raise will need to be removed.
7073
raise
@@ -76,16 +79,18 @@ def submit():
7679
response = None
7780
future = executor.submit(submit)
7881
if not event.wait(timeout):
79-
logging.error("Timed out waiting for extrinsic submission.")
80-
after_timeout_block = substrate.get_block()
82+
logging.error("Timed out waiting for extrinsic submission. Reconnecting.")
83+
# force reconnection of the websocket
84+
subtensor._get_substrate(force=True)
85+
after_timeout_block = subtensor.substrate.get_block()
8186

8287
for block_num in range(
8388
starting_block["header"]["number"],
8489
after_timeout_block["header"]["number"] + 1,
8590
):
86-
block_hash = substrate.get_block_hash(block_num)
91+
block_hash = subtensor.substrate.get_block_hash(block_num)
8792
try:
88-
response = substrate.retrieve_extrinsic_by_hash(
93+
response = subtensor.substrate.retrieve_extrinsic_by_hash(
8994
block_hash, f"0x{extrinsic_hash.hex()}"
9095
)
9196
except ExtrinsicNotFound:

bittensor/core/subtensor.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,17 @@ def close(self):
212212
if self.substrate:
213213
self.substrate.close()
214214

215-
def _get_substrate(self):
216-
"""Establishes a connection to the Substrate node using configured parameters."""
215+
def _get_substrate(self, force: bool = False):
216+
"""
217+
Establishes a connection to the Substrate node using configured parameters.
218+
219+
Args:
220+
force: forces a reconnection if this flag is set
221+
222+
"""
217223
try:
218224
# Set up params.
219-
if self.websocket is None or self.websocket.close_code is not None:
225+
if force or self.websocket is None or self.websocket.close_code is not None:
220226
self.websocket = ws_client.connect(
221227
self.chain_endpoint,
222228
open_timeout=self._connection_timeout,

tests/unit_tests/extrinsics/test_utils.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,37 +9,44 @@
99
)
1010

1111
from bittensor.core.extrinsics import utils
12+
from bittensor.core.subtensor import Subtensor
1213

1314

1415
@pytest.fixture
1516
def set_extrinsics_timeout_env(monkeypatch):
1617
monkeypatch.setenv("EXTRINSIC_SUBMISSION_TIMEOUT", "1")
1718

1819

19-
def test_submit_extrinsic_timeout():
20+
@pytest.fixture
21+
def mock_subtensor():
22+
mock_subtensor = MagicMock(autospec=Subtensor)
23+
mock_substrate = MagicMock(autospec=SubstrateInterface)
24+
mock_subtensor.substrate = mock_substrate
25+
yield mock_subtensor
26+
27+
28+
def test_submit_extrinsic_timeout(mock_subtensor):
2029
timeout = 1
2130

2231
def wait(extrinsic, wait_for_inclusion, wait_for_finalization):
2332
time.sleep(timeout + 0.01)
2433
return True
2534

26-
mock_substrate = MagicMock(autospec=SubstrateInterface)
27-
mock_substrate.submit_extrinsic = wait
35+
mock_subtensor.substrate.submit_extrinsic = wait
2836
mock_extrinsic = MagicMock(autospec=GenericExtrinsic)
2937
with patch.object(utils, "EXTRINSIC_SUBMISSION_TIMEOUT", timeout):
3038
with pytest.raises(SubstrateRequestException):
31-
utils.submit_extrinsic(mock_substrate, mock_extrinsic, True, True)
39+
utils.submit_extrinsic(mock_subtensor, mock_extrinsic, True, True)
3240

3341

34-
def test_submit_extrinsic_success():
35-
mock_substrate = MagicMock(autospec=SubstrateInterface)
36-
mock_substrate.submit_extrinsic.return_value = True
42+
def test_submit_extrinsic_success(mock_subtensor):
43+
mock_subtensor.substrate.submit_extrinsic.return_value = True
3744
mock_extrinsic = MagicMock(autospec=GenericExtrinsic)
38-
result = utils.submit_extrinsic(mock_substrate, mock_extrinsic, True, True)
45+
result = utils.submit_extrinsic(mock_subtensor, mock_extrinsic, True, True)
3946
assert result is True
4047

4148

42-
def test_submit_extrinsic_timeout_env(set_extrinsics_timeout_env):
49+
def test_submit_extrinsic_timeout_env(set_extrinsics_timeout_env, mock_subtensor):
4350
importlib.reload(utils)
4451
timeout = utils.EXTRINSIC_SUBMISSION_TIMEOUT
4552
assert timeout < 5 # should be less than 5 seconds as taken from test env var
@@ -48,23 +55,21 @@ def wait(extrinsic, wait_for_inclusion, wait_for_finalization):
4855
time.sleep(timeout + 1)
4956
return True
5057

51-
mock_substrate = MagicMock(autospec=SubstrateInterface)
52-
mock_substrate.submit_extrinsic = wait
58+
mock_subtensor.substrate.submit_extrinsic = wait
5359
mock_extrinsic = MagicMock(autospec=GenericExtrinsic)
5460
with pytest.raises(SubstrateRequestException):
55-
utils.submit_extrinsic(mock_substrate, mock_extrinsic, True, True)
61+
utils.submit_extrinsic(mock_subtensor, mock_extrinsic, True, True)
5662

5763

58-
def test_submit_extrinsic_success_env(set_extrinsics_timeout_env):
64+
def test_submit_extrinsic_success_env(set_extrinsics_timeout_env, mock_subtensor):
5965
importlib.reload(utils)
60-
mock_substrate = MagicMock(autospec=SubstrateInterface)
61-
mock_substrate.submit_extrinsic.return_value = True
66+
mock_subtensor.substrate.submit_extrinsic.return_value = True
6267
mock_extrinsic = MagicMock(autospec=GenericExtrinsic)
63-
result = utils.submit_extrinsic(mock_substrate, mock_extrinsic, True, True)
68+
result = utils.submit_extrinsic(mock_subtensor, mock_extrinsic, True, True)
6469
assert result is True
6570

6671

67-
def test_submit_extrinsic_timeout_env_float(monkeypatch):
72+
def test_submit_extrinsic_timeout_env_float(monkeypatch, mock_subtensor):
6873
monkeypatch.setenv("EXTRINSIC_SUBMISSION_TIMEOUT", "1.45") # use float
6974

7075
importlib.reload(utils)
@@ -76,11 +81,10 @@ def wait(extrinsic, wait_for_inclusion, wait_for_finalization):
7681
time.sleep(timeout + 0.3) # sleep longer by float
7782
return True
7883

79-
mock_substrate = MagicMock(autospec=SubstrateInterface)
80-
mock_substrate.submit_extrinsic = wait
84+
mock_subtensor.substrate.submit_extrinsic = wait
8185
mock_extrinsic = MagicMock(autospec=GenericExtrinsic)
8286
with pytest.raises(SubstrateRequestException):
83-
utils.submit_extrinsic(mock_substrate, mock_extrinsic, True, True)
87+
utils.submit_extrinsic(mock_subtensor, mock_extrinsic, True, True)
8488

8589

8690
def test_import_timeout_env_parse(monkeypatch):

0 commit comments

Comments
 (0)