Source code for terra_sdk.core.staking.data.validator

from __future__ import annotations

import copy
from datetime import datetime

import attr
from dateutil import parser
from terra_proto.cosmos.staking.v1beta1 import BondStatus
from terra_proto.cosmos.staking.v1beta1 import Commission as Commission_pb
from terra_proto.cosmos.staking.v1beta1 import CommissionRates as CommissionRates_pb
from terra_proto.cosmos.staking.v1beta1 import Description as Description_pb
from terra_proto.cosmos.staking.v1beta1 import Validator as Validator_pb

from terra_sdk.core import Dec, ValAddress, ValConsPubKey
from terra_sdk.util.converter import to_isoformat
from terra_sdk.util.json import JSONSerializable, dict_to_data

__all__ = ["CommissionRates", "Commission", "Description", "Validator", "BondStatus"]


[docs]@attr.s class CommissionRates(JSONSerializable): """Data structure for validator's commission rates & policy.""" rate: Dec = attr.ib(converter=Dec) """Current % commission rate.""" max_rate: Dec = attr.ib(converter=Dec) """Maximum % commission rate permitted by policy.""" max_change_rate: Dec = attr.ib(converter=Dec) """Maximum % change of commission per day.""" def to_amino(self) -> dict: return { "rate": str(self.rate), "max_rate": str(self.max_rate), "max_change_rate": str(self.max_change_rate), } @classmethod def from_data(cls, data: dict) -> CommissionRates: return cls( rate=data["rate"], max_rate=data["max_rate"], max_change_rate=data["max_change_rate"], ) def to_proto(self) -> CommissionRates_pb: return CommissionRates_pb( rate=str(self.rate), max_rate=str(self.max_rate), max_change_rate=str(self.max_change_rate), ) @classmethod def from_proto(cls, proto: CommissionRates_pb) -> CommissionRates: return cls( rate=proto.rate, max_rate=proto.max_rate, max_change_rate=proto.max_change_rate, )
[docs]@attr.s class Commission(JSONSerializable): """Contains information about validator's commission rates.""" commission_rates: CommissionRates = attr.ib() """Validator commission rates.""" update_time: datetime = attr.ib(converter=parser.parse) """Last time commission rates were updated.""" def to_amino(self) -> dict: return { "commission_rates": self.commission_rates.to_amino(), "update_time": to_isoformat(self.update_time), } @classmethod def from_data(cls, data: dict) -> Commission: return cls( commission_rates=CommissionRates.from_data(data["commission_rates"]), update_time=data["update_time"], ) def to_proto(self) -> Commission_pb: return Commission_pb( commission_rates=self.commission_rates.to_proto(), update_time=self.update_time, )
[docs]@attr.s class Description(JSONSerializable): """Validator description entry. Args: moniker: validator name, aka: \"Terran One\" identity: keybase.io identifier (used for setting logo) website: validator website details: longer description of validator security_contact: contact information for validator """ DO_NOT_MODIFY = "[do-not-modify]" """""" moniker: str = attr.ib(default="") identity: str = attr.ib(default="") website: str = attr.ib(default="") details: str = attr.ib(default="") security_contact: str = attr.ib(default="") def to_amino(self) -> dict: return { "moniker": self.moniker, "identity": self.identity, "website": self.website, "details": self.details, "security_contact": self.security_contact, } @classmethod def from_data(cls, data) -> Description: return cls( data.get("moniker"), data.get("identity"), data.get("website"), data.get("details"), data.get("security_contact"), ) def to_proto(self) -> Description_pb: return Description_pb( moniker=self.moniker, identity=self.identity, website=self.website, details=self.details, security_contact=self.security_contact, )
[docs]@attr.s class Validator(JSONSerializable): """Contains information about a registered validator.""" operator_address: ValAddress = attr.ib() """""" consensus_pubkey: ValConsPubKey = attr.ib() """""" jailed: bool = attr.ib(converter=bool) """""" status: BondStatus = attr.ib(converter=BondStatus) """""" tokens: int = attr.ib(converter=int) """""" delegator_shares: Dec = attr.ib(converter=Dec) """""" description: Description = attr.ib() """""" unbonding_height: int = attr.ib(converter=int) """""" unbonding_time: datetime = attr.ib(converter=parser.parse) """""" commission: Commission = attr.ib() """""" min_self_delegation: int = attr.ib(converter=int) """""" def to_amino(self) -> dict: return { "operator_address": self.operator_address, "consensus_pubkey": self.consensus_pubkey.to_amino(), "jailed": self.jailed, "status": self.status, "tokens": str(self.tokens), "delegator_shares": str(self.delegator_shares), "description": self.description.to_amino(), "unbonding_height": str(self.unbonding_height), "unbonding_time": to_isoformat(self.unbonding_time), "commission": self.commission.to_amino(), "min_self_delegation": str(self.min_self_delegation), }
[docs] def to_data(self) -> dict: d = copy.deepcopy(self.__dict__) d["min_self_delegation"] = str(d["min_self_delegation"]) d["tokens"] = str(d["tokens"]) d["unbonding_height"] = str(d["unbonding_height"]) return dict_to_data(d)
@classmethod def from_data(cls, data: dict) -> Validator: return cls( operator_address=data["operator_address"], consensus_pubkey=data["consensus_pubkey"], jailed=data.get("jailed"), status=BondStatus.from_string(data["status"]), tokens=data["tokens"], delegator_shares=data["delegator_shares"], description=Description.from_data(data["description"]), unbonding_height=data.get("unbonding_height") or 0, unbonding_time=data["unbonding_time"], commission=Commission.from_data(data["commission"]), min_self_delegation=data["min_self_delegation"], ) def to_proto(self) -> Validator_pb: return Validator_pb( operator_address=self.operator_address, consensus_pubkey=self.consensus_pubkey.to_proto(), jailed=self.jailed, status=self.status, tokens=str(self.tokens), delegator_shares=str(self.delegator_shares), description=self.description.to_proto(), unbonding_height=self.unbonding_height, unbonding_time=self.unbonding_time, commission=self.commission.to_proto(), min_self_delegation=str(self.min_self_delegation), )