Skip to content

Commit 403dbf5

Browse files
Merge branch 'staging' into fix/zyzniewski/wait_epoch
2 parents a60fd83 + fee2eaf commit 403dbf5

File tree

8 files changed

+345
-23
lines changed

8 files changed

+345
-23
lines changed

bittensor/core/async_subtensor.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,10 +2020,11 @@ async def get_vote_data(
20202020
block_hash=block_hash,
20212021
reuse_block_hash=reuse_block,
20222022
)
2023+
20232024
if vote_data is None:
20242025
return None
2025-
else:
2026-
return ProposalVoteData(vote_data)
2026+
2027+
return ProposalVoteData.from_dict(vote_data)
20272028

20282029
async def get_uid_for_hotkey_on_subnet(
20292030
self,
Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
1+
from dataclasses import dataclass
2+
3+
from bittensor.core.chain_data.info_base import InfoBase
14
from bittensor.core.chain_data.utils import decode_account_id
25

36

4-
# Senate / Proposal data
5-
class ProposalVoteData:
7+
@dataclass
8+
class ProposalVoteData(InfoBase):
9+
"""
10+
Senate / Proposal data
11+
"""
12+
613
index: int
714
threshold: int
815
ayes: list[str]
916
nays: list[str]
1017
end: int
1118

12-
def __init__(self, proposal_dict: dict) -> None:
13-
self.index = proposal_dict["index"]
14-
self.threshold = proposal_dict["threshold"]
15-
self.ayes = self.decode_ss58_tuples(proposal_dict["ayes"])
16-
self.nays = self.decode_ss58_tuples(proposal_dict["nays"])
17-
self.end = proposal_dict["end"]
18-
19-
@staticmethod
20-
def decode_ss58_tuples(line: tuple):
21-
"""Decodes a tuple of ss58 addresses formatted as bytes tuples."""
22-
return [decode_account_id(line[x][0]) for x in range(len(line))]
19+
@classmethod
20+
def from_dict(cls, proposal_dict: dict) -> "ProposalVoteData":
21+
return cls(
22+
ayes=[decode_account_id(key) for key in proposal_dict["ayes"]],
23+
end=proposal_dict["end"],
24+
index=proposal_dict["index"],
25+
nays=[decode_account_id(key) for key in proposal_dict["nays"]],
26+
threshold=proposal_dict["threshold"],
27+
)

bittensor/core/subtensor.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,10 +1579,11 @@ def get_vote_data(
15791579
params=[proposal_hash],
15801580
block_hash=self.determine_block_hash(block),
15811581
)
1582+
15821583
if vote_data is None:
15831584
return None
1584-
else:
1585-
return ProposalVoteData(vote_data)
1585+
1586+
return ProposalVoteData.from_dict(vote_data)
15861587

15871588
def get_uid_for_hotkey_on_subnet(
15881589
self, hotkey_ss58: str, netuid: int, block: Optional[int] = None

tests/e2e_tests/test_delegate.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
import bittensor
44
from bittensor.core.chain_data.chain_identity import ChainIdentity
55
from bittensor.core.chain_data.delegate_info import DelegatedInfo, DelegateInfo
6+
from bittensor.core.chain_data.proposal_vote_data import ProposalVoteData
67
from bittensor.utils.balance import Balance
78
from tests.e2e_tests.utils.chain_interactions import (
9+
propose,
810
set_identity,
911
sudo_set_admin_utils,
12+
vote,
1013
)
14+
from tests.helpers.helpers import CLOSE_IN_VALUE
1115

1216
DEFAULT_DELEGATE_TAKE = 0.179995422293431
1317

@@ -321,3 +325,105 @@ def test_nominator_min_required_stake(local_chain, subtensor, alice_wallet, bob_
321325
)
322326

323327
assert stake == Balance(0)
328+
329+
330+
def test_get_vote_data(subtensor, alice_wallet):
331+
"""
332+
Tests:
333+
- Sends Propose
334+
- Checks existing Proposals
335+
- Votes
336+
- Checks Proposal is updated
337+
"""
338+
339+
subtensor.root_register(alice_wallet)
340+
341+
proposals = subtensor.query_map(
342+
"Triumvirate",
343+
"ProposalOf",
344+
params=[],
345+
)
346+
347+
assert proposals.records == []
348+
349+
success, error = propose(
350+
subtensor,
351+
alice_wallet,
352+
proposal=subtensor.substrate.compose_call(
353+
call_module="Triumvirate",
354+
call_function="set_members",
355+
call_params={
356+
"new_members": [],
357+
"prime": None,
358+
"old_count": 0,
359+
},
360+
),
361+
duration=1_000_000,
362+
)
363+
364+
assert error == ""
365+
assert success is True
366+
367+
proposals = subtensor.query_map(
368+
"Triumvirate",
369+
"ProposalOf",
370+
params=[],
371+
)
372+
proposals = {
373+
bytes(proposal_hash[0]): proposal.value for proposal_hash, proposal in proposals
374+
}
375+
376+
assert list(proposals.values()) == [
377+
{
378+
"Triumvirate": (
379+
{
380+
"set_members": {
381+
"new_members": (),
382+
"prime": None,
383+
"old_count": 0,
384+
},
385+
},
386+
),
387+
},
388+
]
389+
390+
proposal_hash = list(proposals.keys())[0]
391+
proposal_hash = f"0x{proposal_hash.hex()}"
392+
393+
proposal = subtensor.get_vote_data(
394+
proposal_hash,
395+
)
396+
397+
assert proposal == ProposalVoteData(
398+
ayes=[],
399+
end=CLOSE_IN_VALUE(1_000_000, subtensor.block),
400+
index=0,
401+
nays=[],
402+
threshold=3,
403+
)
404+
405+
success, error = vote(
406+
subtensor,
407+
alice_wallet,
408+
alice_wallet.hotkey.ss58_address,
409+
proposal_hash,
410+
index=0,
411+
approve=True,
412+
)
413+
414+
assert error == ""
415+
assert success is True
416+
417+
proposal = subtensor.get_vote_data(
418+
proposal_hash,
419+
)
420+
421+
assert proposal == ProposalVoteData(
422+
ayes=[
423+
alice_wallet.hotkey.ss58_address,
424+
],
425+
end=CLOSE_IN_VALUE(1_000_000, subtensor.block),
426+
index=0,
427+
nays=[],
428+
threshold=3,
429+
)

tests/e2e_tests/test_incentive.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,26 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa
105105
assert alice_neuron.rank < 0.5
106106

107107
bob_neuron = metagraph.neurons[1]
108+
108109
assert bob_neuron.incentive > 0.5
109110
assert bob_neuron.consensus > 0.5
110111
assert bob_neuron.rank > 0.5
111112
assert bob_neuron.trust == 1
112113

114+
bonds = subtensor.bonds(netuid)
115+
116+
assert bonds == [
117+
(
118+
0,
119+
[
120+
(0, 65535),
121+
(1, 65535),
122+
],
123+
),
124+
(
125+
1,
126+
[],
127+
),
128+
]
129+
113130
print("✅ Passed test_incentive")

tests/e2e_tests/test_staking.py

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,3 +516,151 @@ def test_safe_swap_stake_scenarios(subtensor, alice_wallet, bob_wallet):
516516
assert dest_stake > Balance(
517517
0
518518
), "Destination stake should be non-zero after successful swap"
519+
520+
521+
def test_move_stake(subtensor, alice_wallet, bob_wallet):
522+
"""
523+
Tests:
524+
- Adding stake
525+
- Moving stake from one hotkey-subnet pair to another
526+
"""
527+
528+
subtensor.burned_register(
529+
alice_wallet,
530+
netuid=1,
531+
wait_for_inclusion=True,
532+
wait_for_finalization=True,
533+
)
534+
535+
assert subtensor.add_stake(
536+
alice_wallet,
537+
alice_wallet.hotkey.ss58_address,
538+
netuid=1,
539+
amount=Balance.from_tao(1_000),
540+
wait_for_inclusion=True,
541+
wait_for_finalization=True,
542+
)
543+
544+
stakes = subtensor.get_stake_for_coldkey(alice_wallet.coldkey.ss58_address)
545+
546+
assert stakes == [
547+
StakeInfo(
548+
hotkey_ss58=alice_wallet.hotkey.ss58_address,
549+
coldkey_ss58=alice_wallet.coldkey.ss58_address,
550+
netuid=1,
551+
stake=ANY_BALANCE,
552+
locked=Balance(0),
553+
emission=ANY_BALANCE,
554+
drain=0,
555+
is_registered=True,
556+
),
557+
]
558+
559+
subtensor.register_subnet(bob_wallet)
560+
561+
assert subtensor.move_stake(
562+
alice_wallet,
563+
origin_hotkey=alice_wallet.hotkey.ss58_address,
564+
origin_netuid=1,
565+
destination_hotkey=bob_wallet.hotkey.ss58_address,
566+
destination_netuid=2,
567+
amount=stakes[0].stake,
568+
wait_for_finalization=True,
569+
wait_for_inclusion=True,
570+
)
571+
572+
stakes = subtensor.get_stake_for_coldkey(alice_wallet.coldkey.ss58_address)
573+
574+
assert stakes == [
575+
StakeInfo(
576+
hotkey_ss58=bob_wallet.hotkey.ss58_address,
577+
coldkey_ss58=alice_wallet.coldkey.ss58_address,
578+
netuid=2,
579+
stake=ANY_BALANCE,
580+
locked=Balance(0),
581+
emission=ANY_BALANCE,
582+
drain=0,
583+
is_registered=True,
584+
),
585+
]
586+
587+
588+
def test_transfer_stake(subtensor, alice_wallet, bob_wallet, dave_wallet):
589+
"""
590+
Tests:
591+
- Adding stake
592+
- Transfering stake from one coldkey-subnet pair to another
593+
"""
594+
595+
subtensor.burned_register(
596+
alice_wallet,
597+
netuid=1,
598+
wait_for_inclusion=True,
599+
wait_for_finalization=True,
600+
)
601+
602+
assert subtensor.add_stake(
603+
alice_wallet,
604+
alice_wallet.hotkey.ss58_address,
605+
netuid=1,
606+
amount=Balance.from_tao(1_000),
607+
wait_for_inclusion=True,
608+
wait_for_finalization=True,
609+
)
610+
611+
alice_stakes = subtensor.get_stake_for_coldkey(alice_wallet.coldkey.ss58_address)
612+
613+
assert alice_stakes == [
614+
StakeInfo(
615+
hotkey_ss58=alice_wallet.hotkey.ss58_address,
616+
coldkey_ss58=alice_wallet.coldkey.ss58_address,
617+
netuid=1,
618+
stake=ANY_BALANCE,
619+
locked=Balance(0),
620+
emission=ANY_BALANCE,
621+
drain=0,
622+
is_registered=True,
623+
),
624+
]
625+
626+
bob_stakes = subtensor.get_stake_for_coldkey(bob_wallet.coldkey.ss58_address)
627+
628+
assert bob_stakes == []
629+
630+
subtensor.register_subnet(dave_wallet)
631+
subtensor.burned_register(
632+
bob_wallet,
633+
netuid=2,
634+
wait_for_inclusion=True,
635+
wait_for_finalization=True,
636+
)
637+
638+
assert subtensor.transfer_stake(
639+
alice_wallet,
640+
destination_coldkey_ss58=bob_wallet.coldkey.ss58_address,
641+
hotkey_ss58=alice_wallet.hotkey.ss58_address,
642+
origin_netuid=1,
643+
destination_netuid=2,
644+
amount=alice_stakes[0].stake,
645+
wait_for_inclusion=True,
646+
wait_for_finalization=True,
647+
)
648+
649+
alice_stakes = subtensor.get_stake_for_coldkey(alice_wallet.coldkey.ss58_address)
650+
651+
assert alice_stakes == []
652+
653+
bob_stakes = subtensor.get_stake_for_coldkey(bob_wallet.coldkey.ss58_address)
654+
655+
assert bob_stakes == [
656+
StakeInfo(
657+
hotkey_ss58=alice_wallet.hotkey.ss58_address,
658+
coldkey_ss58=bob_wallet.coldkey.ss58_address,
659+
netuid=2,
660+
stake=ANY_BALANCE,
661+
locked=Balance(0),
662+
emission=ANY_BALANCE,
663+
drain=0,
664+
is_registered=False,
665+
),
666+
]

0 commit comments

Comments
 (0)