Skip to content

Commit b1b8748

Browse files
committed
Makes things work with the proxy logic
1 parent 0780305 commit b1b8748

File tree

6 files changed

+169
-201
lines changed

6 files changed

+169
-201
lines changed

bittensor_cli/src/bittensor/extrinsics/mev_shield.py

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -57,56 +57,6 @@ async def encrypt_extrinsic(
5757
return encrypted_call
5858

5959

60-
async def create_mev_protected_extrinsic(
61-
subtensor: "SubtensorInterface",
62-
keypair: "Keypair",
63-
call: "GenericCall",
64-
nonce: int,
65-
era: Optional[int] = None,
66-
) -> tuple["GenericExtrinsic", str]:
67-
"""
68-
Create a MEV-protected extrinsic.
69-
70-
This function handles MEV Shield wrapping:
71-
1. Fetches a future nonce (current_nonce + 1) & signs the inner call with it
72-
2. Encrypts it into a wrapper call
73-
3. Signs the wrapper with the current nonce
74-
75-
Args:
76-
subtensor: The SubtensorInterface instance.
77-
keypair: Keypair for signing.
78-
call: The call to protect (e.g., add_stake).
79-
nonce: The current account nonce (wrapper will use this, inner uses nonce+1).
80-
era: The era period for the extrinsic.
81-
82-
Returns:
83-
Tuple of (signed_shield_extrinsic, inner_extrinsic_hash).
84-
The inner_extrinsic_hash is used for tracking actual extrinsic.
85-
"""
86-
87-
async def create_signed(call_to_sign, n):
88-
kwargs = {
89-
"call": call_to_sign,
90-
"keypair": keypair,
91-
"nonce": n,
92-
}
93-
if era is not None:
94-
kwargs["era"] = {"period": era}
95-
return await subtensor.substrate.create_signed_extrinsic(**kwargs)
96-
97-
next_nonce = await subtensor.substrate.get_account_next_index(keypair.ss58_address)
98-
99-
# Actual call: Sign with future nonce (current_nonce + 1)
100-
inner_extrinsic = await create_signed(call, next_nonce)
101-
inner_hash = f"0x{inner_extrinsic.extrinsic_hash.hex()}"
102-
103-
# MeV Shield wrapper: Sign with current nonce
104-
shield_call = await encrypt_extrinsic(subtensor, inner_extrinsic)
105-
shield_extrinsic = await create_signed(shield_call, nonce)
106-
107-
return shield_extrinsic, inner_hash
108-
109-
11060
async def extract_mev_shield_id(response: "AsyncExtrinsicReceipt") -> Optional[str]:
11161
"""
11262
Extract the MEV Shield wrapper ID from an extrinsic response.

bittensor_cli/src/bittensor/subtensor_interface.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from bittensor_cli.src import DelegatesDetails
3535
from bittensor_cli.src.bittensor.balances import Balance, fixed_to_float
3636
from bittensor_cli.src import Constants, defaults, TYPE_REGISTRY
37+
from bittensor_cli.src.bittensor.extrinsics.mev_shield import encrypt_extrinsic
3738
from bittensor_cli.src.bittensor.utils import (
3839
format_error_message,
3940
console,
@@ -2406,6 +2407,7 @@ async def get_all_subnet_ema_tao_inflow(
24062407
else:
24072408
_, raw_ema_value = value
24082409
ema_value = fixed_to_float(raw_ema_value)
2410+
# TODO @abe is this intentional: float passed as int for from_rao
24092411
ema_map[netuid] = Balance.from_rao(ema_value)
24102412
return ema_map
24112413

@@ -2437,12 +2439,13 @@ async def get_subnet_ema_tao_inflow(
24372439
return Balance.from_rao(0)
24382440
_, raw_ema_value = value
24392441
ema_value = fixed_to_float(raw_ema_value)
2442+
# TODO @abe this is a float, but we're passing it as an int for from_rao, is this intentional?
24402443
return Balance.from_rao(ema_value)
24412444

24422445
async def get_mev_shield_next_key(
24432446
self,
24442447
block_hash: Optional[str] = None,
2445-
) -> Optional[tuple[bytes, int]]:
2448+
) -> bytes:
24462449
"""
24472450
Get the next MEV Shield public key and epoch from chain storage.
24482451
@@ -2470,7 +2473,7 @@ async def get_mev_shield_next_key(
24702473
async def get_mev_shield_current_key(
24712474
self,
24722475
block_hash: Optional[str] = None,
2473-
) -> Optional[tuple[bytes, int]]:
2476+
) -> bytes:
24742477
"""
24752478
Get the current MEV Shield public key and epoch from chain storage.
24762479

bittensor_cli/src/commands/stake/add.py

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from bittensor_cli.src import COLOR_PALETTE
1212
from bittensor_cli.src.bittensor.balances import Balance
1313
from bittensor_cli.src.bittensor.extrinsics.mev_shield import (
14-
create_mev_protected_extrinsic,
1514
extract_mev_shield_id,
1615
wait_for_extrinsic_by_hash,
1716
)
@@ -141,14 +140,13 @@ async def safe_stake_extrinsic(
141140
},
142141
),
143142
)
144-
if mev_protection:
145-
call = await encrypt_call(subtensor, wallet, call)
146143
success_, err_msg, response = await subtensor.sign_and_send_extrinsic(
147144
call=call,
148145
wallet=wallet,
149146
nonce=next_nonce,
150147
era={"period": era},
151148
proxy=proxy,
149+
mev_protection=mev_protection,
152150
)
153151
if not success_:
154152
if "Custom error: 8" in err_msg:
@@ -164,16 +162,20 @@ async def safe_stake_extrinsic(
164162
return False, err_msg, None
165163
else:
166164
if mev_protection:
165+
inner_hash = err_msg
167166
mev_shield_id = await extract_mev_shield_id(response)
168-
if mev_shield_id:
169-
mev_success, mev_error, response = await wait_for_mev_execution(
170-
subtensor, mev_shield_id, response.block_hash, status=status_
171-
)
172-
if not mev_success:
173-
status_.stop()
174-
err_msg = f"{failure_prelude}: {mev_error}"
175-
err_out("\n" + err_msg)
176-
return False, err_msg, None
167+
mev_success, mev_error, response = await wait_for_extrinsic_by_hash(
168+
subtensor=subtensor,
169+
extrinsic_hash=inner_hash,
170+
shield_id=mev_shield_id,
171+
submit_block_hash=response.block_hash,
172+
status=status_,
173+
)
174+
if not mev_success:
175+
status_.stop()
176+
err_msg = f"{failure_prelude}: {mev_error}"
177+
err_out("\n" + err_msg)
178+
return False, err_msg, None
177179
if json_output:
178180
# the rest of this checking is not necessary if using json_output
179181
return True, "", response
@@ -239,31 +241,34 @@ async def stake_extrinsic(
239241
failure_prelude = (
240242
f":cross_mark: [red]Failed[/red] to stake {amount} on Netuid {netuid_i}"
241243
)
242-
if mev_protection:
243-
call = await encrypt_call(subtensor, wallet, call)
244244
success_, err_msg, response = await subtensor.sign_and_send_extrinsic(
245245
call=call,
246246
wallet=wallet,
247247
nonce=next_nonce,
248248
era={"period": era},
249249
proxy=proxy,
250+
mev_protection=mev_protection,
250251
)
251252
if not success_:
252253
err_msg = f"{failure_prelude} with error: {err_msg}"
253254
err_out("\n" + err_msg)
254255
return False, err_msg, None
255256
else:
256257
if mev_protection:
258+
inner_hash = err_msg
257259
mev_shield_id = await extract_mev_shield_id(response)
258-
if mev_shield_id:
259-
mev_success, mev_error, response = await wait_for_mev_execution(
260-
subtensor, mev_shield_id, response.block_hash, status=status_
261-
)
262-
if not mev_success:
263-
status_.stop()
264-
err_msg = f"{failure_prelude}: {mev_error}"
265-
err_out("\n" + err_msg)
266-
return False, err_msg, None
260+
mev_success, mev_error, response = await wait_for_extrinsic_by_hash(
261+
subtensor=subtensor,
262+
extrinsic_hash=inner_hash,
263+
shield_id=mev_shield_id,
264+
submit_block_hash=response.block_hash,
265+
status=status_,
266+
)
267+
if not mev_success:
268+
status_.stop()
269+
err_msg = f"{failure_prelude}: {mev_error}"
270+
err_out("\n" + err_msg)
271+
return False, err_msg, None
267272
if json_output:
268273
# the rest of this is not necessary if using json_output
269274
return True, "", response

0 commit comments

Comments
 (0)