-
Notifications
You must be signed in to change notification settings - Fork 209
feat: add staking_info fields to ContractInfo #1744
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
78fe85e
8fe7319
a535158
6c5e374
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -11,6 +11,9 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1. | |||||||||||
|
|
||||||||||||
| ### Examples | ||||||||||||
|
|
||||||||||||
| ### Added | ||||||||||||
| - Add staking_info fields (`staked_account_id`, `staked_node_id`, `decline_staking_reward`) to ContractInfo class to expose staking metadata from protobuf. (#1365) | ||||||||||||
|
Comment on lines
+14
to
+15
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing blank line below heading (MD022). The Proposed fix ### Added
+
- Add staking_info fields (`staked_account_id`, `staked_node_id`, `decline_staking_reward`) to ContractInfo class to expose staking metadata from protobuf. (`#1365`)📝 Committable suggestion
Suggested change
🧰 Tools🪛 markdownlint-cli2 (0.20.0)[warning] 14-14: Headings should be surrounded by blank lines (MD022, blanks-around-headings) |
||||||||||||
|
|
||||||||||||
| ### Docs | ||||||||||||
| - Improved Google-style docstring for `compress_point_unchecked` in `crypto_utils.py`. (#1625) | ||||||||||||
| - chore: update office hours and community calls to use direct links (`#1804`) | ||||||||||||
|
|
||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,9 +9,9 @@ | |
| from hiero_sdk_python.account.account_id import AccountId | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe PR #1595 is already addressing this issue. We can remove this change from the current PR to avoid duplication and keep the scope focused.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh, sorry, didn't see that there is another PR for the |
||
| from hiero_sdk_python.crypto.public_key import PublicKey | ||
| from hiero_sdk_python.Duration import Duration | ||
| from hiero_sdk_python.hapi.services.basic_types_pb2 import StakingInfo | ||
| from hiero_sdk_python.hapi.services.crypto_get_info_pb2 import CryptoGetInfoResponse | ||
| from hiero_sdk_python.hbar import Hbar | ||
| from hiero_sdk_python.staking_info import StakingInfo | ||
| from hiero_sdk_python.timestamp import Timestamp | ||
| from hiero_sdk_python.tokens.token_relationship import TokenRelationship | ||
|
|
||
|
|
@@ -38,9 +38,7 @@ class AccountInfo: | |
| associated with this account. | ||
| account_memo (Optional[str]): The memo associated with this account. | ||
| owned_nfts (Optional[int]): The number of NFTs owned by this account. | ||
| staked_account_id (Optional[AccountId]): The account to which this account is staked. | ||
| staked_node_id (Optional[int]): The node to which this account is staked. | ||
| decline_staking_reward (bool): Whether this account declines receiving staking rewards. | ||
| staking_info (Optional[StakingInfo]): The staking information for this account. | ||
| """ | ||
|
|
||
| account_id: Optional[AccountId] = None | ||
|
|
@@ -56,9 +54,7 @@ class AccountInfo: | |
| account_memo: Optional[str] = None | ||
| owned_nfts: Optional[int] = None | ||
| max_automatic_token_associations: Optional[int] = None | ||
| staked_account_id: Optional[AccountId] = None | ||
| staked_node_id: Optional[int] = None | ||
| decline_staking_reward: Optional[bool] = None | ||
| staking_info: Optional[StakingInfo] = None | ||
|
Comment on lines
-59
to
+57
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the removal of |
||
|
|
||
| @classmethod | ||
| def _from_proto(cls, proto: CryptoGetInfoResponse.AccountInfo) -> "AccountInfo": | ||
|
|
@@ -100,21 +96,13 @@ def _from_proto(cls, proto: CryptoGetInfoResponse.AccountInfo) -> "AccountInfo": | |
| account_memo=proto.memo, | ||
| owned_nfts=proto.ownedNfts, | ||
| max_automatic_token_associations=proto.max_automatic_token_associations, | ||
| staking_info=( | ||
| StakingInfo._from_proto(proto.staking_info) | ||
| if proto.HasField('staking_info') | ||
| else None | ||
| ), | ||
| ) | ||
|
|
||
| staking_info = proto.staking_info if proto.HasField('staking_info') else None | ||
|
|
||
| if staking_info: | ||
| account_info.staked_account_id = ( | ||
| AccountId._from_proto(staking_info.staked_account_id) | ||
| if staking_info.HasField('staked_account_id') else None | ||
| ) | ||
| account_info.staked_node_id = ( | ||
| staking_info.staked_node_id | ||
| if staking_info.HasField('staked_node_id') else None | ||
| ) | ||
| account_info.decline_staking_reward = staking_info.decline_reward | ||
|
|
||
| return account_info | ||
|
|
||
| def _to_proto(self) -> CryptoGetInfoResponse.AccountInfo: | ||
|
|
@@ -147,11 +135,7 @@ def _to_proto(self) -> CryptoGetInfoResponse.AccountInfo: | |
| memo=self.account_memo, | ||
| ownedNfts=self.owned_nfts, | ||
| max_automatic_token_associations=self.max_automatic_token_associations, | ||
| staking_info=StakingInfo( | ||
| staked_account_id=self.staked_account_id._to_proto() if self.staked_account_id else None, | ||
| staked_node_id=self.staked_node_id if self.staked_node_id else None, | ||
| decline_reward=self.decline_staking_reward | ||
| ), | ||
| staking_info=self.staking_info._to_proto() if self.staking_info else None, | ||
| ) | ||
|
|
||
| def __str__(self) -> str: | ||
|
|
@@ -166,11 +150,10 @@ def __str__(self) -> str: | |
| (self.account_memo, "Memo"), | ||
| (self.owned_nfts, "Owned NFTs"), | ||
| (self.max_automatic_token_associations, "Max Automatic Token Associations"), | ||
| (self.staked_account_id, "Staked Account ID"), | ||
| (self.staked_node_id, "Staked Node ID"), | ||
| (self.proxy_received, "Proxy Received"), | ||
| (self.expiration_time, "Expiration Time"), | ||
| (self.auto_renew_period, "Auto Renew Period"), | ||
| (self.staking_info, "Staking Info"), | ||
| ] | ||
|
|
||
| # Use a list comprehension to process simple fields (reduces complexity score) | ||
|
|
@@ -182,9 +165,6 @@ def __str__(self) -> str: | |
|
|
||
| if self.receiver_signature_required is not None: | ||
| lines.append(f"Receiver Signature Required: {self.receiver_signature_required}") | ||
|
|
||
| if self.decline_staking_reward is not None: | ||
| lines.append(f"Decline Staking Reward: {self.decline_staking_reward}") | ||
|
|
||
| if self.token_relationships: | ||
| lines.append(f"Token Relationships: {len(self.token_relationships)}") | ||
|
|
@@ -202,7 +182,6 @@ def __repr__(self) -> str: | |
| f"receiver_signature_required={self.receiver_signature_required!r}, " | ||
| f"owned_nfts={self.owned_nfts!r}, " | ||
| f"account_memo={self.account_memo!r}, " | ||
| f"staked_node_id={self.staked_node_id!r}, " | ||
| f"staked_account_id={self.staked_account_id!r}" | ||
| f"staking_info={self.staking_info!r}" | ||
| f")" | ||
| ) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,8 @@ | |
| from hiero_sdk_python.tokens.token_relationship import TokenRelationship | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test can also be remove due to same |
||
| from hiero_sdk_python.tokens.token_id import TokenId | ||
| from hiero_sdk_python.hapi.services.crypto_get_info_pb2 import CryptoGetInfoResponse | ||
| from hiero_sdk_python.hapi.services.basic_types_pb2 import StakingInfo as StakingInfoProto | ||
| from hiero_sdk_python.staking_info import StakingInfo | ||
|
|
||
| pytestmark = pytest.mark.unit | ||
|
|
||
|
|
@@ -210,3 +212,155 @@ def test_str_and_repr(account_info): | |
| assert "account_id=AccountId(shard=0, realm=0, num=100" in info_repr | ||
| assert "contract_account_id='0.0.100'" in info_repr | ||
| assert "account_memo='Test account memo'" in info_repr | ||
|
|
||
|
|
||
| def test_from_proto_with_staking_info(): | ||
| """Test from_proto with staking account info""" | ||
| public_key = PrivateKey.generate_ed25519().public_key() | ||
| proto = CryptoGetInfoResponse.AccountInfo( | ||
| accountID=AccountId(0, 0, 100)._to_proto(), | ||
| key=public_key._to_proto(), | ||
| balance=5000000, | ||
| staking_info=StakingInfoProto( | ||
| staked_account_id=AccountId(0, 0, 500)._to_proto(), | ||
| decline_reward=True, | ||
| ), | ||
| ) | ||
|
|
||
| account_info = AccountInfo._from_proto(proto) | ||
|
|
||
| assert account_info.staking_info is not None | ||
| assert account_info.staking_info.staked_account_id == AccountId(0, 0, 500) | ||
| assert account_info.staking_info.decline_reward is True | ||
|
|
||
|
|
||
| def test_from_proto_with_staked_node_id(): | ||
| """Test from_proto with staked_node_id""" | ||
| public_key = PrivateKey.generate_ed25519().public_key() | ||
| proto = CryptoGetInfoResponse.AccountInfo( | ||
| accountID=AccountId(0, 0, 100)._to_proto(), | ||
| key=public_key._to_proto(), | ||
| balance=5000000, | ||
| staking_info=StakingInfoProto( | ||
| staked_node_id=3, | ||
| decline_reward=False, | ||
| ), | ||
| ) | ||
|
|
||
| account_info = AccountInfo._from_proto(proto) | ||
|
|
||
| assert account_info.staking_info is not None | ||
| assert account_info.staking_info.staked_node_id == 3 | ||
| assert account_info.staking_info.decline_reward is False | ||
|
|
||
|
|
||
| def test_from_proto_with_no_staking_info(): | ||
| """Test from_proto without staking info""" | ||
| public_key = PrivateKey.generate_ed25519().public_key() | ||
| proto = CryptoGetInfoResponse.AccountInfo( | ||
| accountID=AccountId(0, 0, 100)._to_proto(), | ||
| key=public_key._to_proto(), | ||
| balance=5000000, | ||
| ) | ||
|
|
||
| account_info = AccountInfo._from_proto(proto) | ||
|
|
||
| assert account_info.staking_info is None | ||
|
|
||
|
|
||
| def test_to_proto_with_staking_info(): | ||
| """Test to_proto with staking info""" | ||
| account_info = AccountInfo( | ||
| account_id=AccountId(0, 0, 100), | ||
| balance=Hbar.from_tinybars(5000000), | ||
| staking_info=StakingInfo( | ||
| staked_account_id=AccountId(0, 0, 500), | ||
| decline_reward=True, | ||
| ), | ||
| ) | ||
|
|
||
| proto = account_info._to_proto() | ||
|
|
||
| assert proto.HasField('staking_info') | ||
| assert proto.staking_info.HasField('staked_account_id') | ||
| assert proto.staking_info.staked_account_id == AccountId(0, 0, 500)._to_proto() | ||
| assert proto.staking_info.decline_reward is True | ||
|
|
||
|
|
||
| def test_to_proto_with_staked_node_id(): | ||
| """Test to_proto with staked_node_id""" | ||
| account_info = AccountInfo( | ||
| account_id=AccountId(0, 0, 100), | ||
| balance=Hbar.from_tinybars(5000000), | ||
| staking_info=StakingInfo( | ||
| staked_node_id=5, | ||
| decline_reward=False, | ||
| ), | ||
| ) | ||
|
|
||
| proto = account_info._to_proto() | ||
|
|
||
| assert proto.HasField('staking_info') | ||
| assert proto.staking_info.staked_node_id == 5 | ||
| assert proto.staking_info.decline_reward is False | ||
|
|
||
|
|
||
| def test_proto_conversion_staking_node_round_trip(): | ||
| """Test proto conversion round trip with staked_node_id""" | ||
| account_info = AccountInfo( | ||
| account_id=AccountId(0, 0, 100), | ||
| key=PrivateKey.generate_ed25519().public_key(), | ||
| balance=Hbar.from_tinybars(5000000), | ||
| staking_info=StakingInfo( | ||
| staked_node_id=7, | ||
| decline_reward=False, | ||
| ), | ||
| ) | ||
|
|
||
| converted = AccountInfo._from_proto(account_info._to_proto()) | ||
|
|
||
| assert converted.account_id == account_info.account_id | ||
| assert converted.balance.to_tinybars() == account_info.balance.to_tinybars() | ||
| assert converted.staking_info.staked_account_id is None | ||
| assert converted.staking_info.staked_node_id == 7 | ||
| assert converted.staking_info.decline_reward is False | ||
|
|
||
|
|
||
| def test_proto_conversion_staking_account_round_trip(): | ||
| """Test proto conversion round trip with staked_account_id""" | ||
| account_info = AccountInfo( | ||
| account_id=AccountId(0, 0, 100), | ||
| key=PrivateKey.generate_ed25519().public_key(), | ||
| balance=Hbar.from_tinybars(5000000), | ||
| staking_info=StakingInfo( | ||
| staked_account_id=AccountId(0, 0, 600), | ||
| decline_reward=True, | ||
| ), | ||
| ) | ||
|
|
||
| converted = AccountInfo._from_proto(account_info._to_proto()) | ||
|
|
||
| assert converted.account_id == account_info.account_id | ||
| assert converted.balance.to_tinybars() == account_info.balance.to_tinybars() | ||
| assert converted.staking_info.staked_account_id == AccountId(0, 0, 600) | ||
| assert converted.staking_info.staked_node_id is None | ||
| assert converted.staking_info.decline_reward is True | ||
|
|
||
|
|
||
| def test_proto_conversion_with_staked_node_zero(): | ||
| """Test proto conversion with staked_node_id set to 0""" | ||
| account_info = AccountInfo( | ||
| account_id=AccountId(0, 0, 100), | ||
| key=PrivateKey.generate_ed25519().public_key(), | ||
| balance=Hbar.from_tinybars(5000000), | ||
| staking_info=StakingInfo( | ||
| staked_node_id=0, | ||
| decline_reward=True, | ||
| ), | ||
| ) | ||
|
|
||
| converted = AccountInfo._from_proto(account_info._to_proto()) | ||
|
|
||
| assert converted.staking_info is not None | ||
| assert converted.staking_info.staked_node_id == 0 | ||
| assert converted.staking_info.decline_reward is True | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move this under Src section