def divide_stake(self, stake_index: int, target_value: NU, additional_periods: int = None, expiration: maya.MayaDT = None) -> tuple: # Calculate duration in periods if additional_periods and expiration: raise ValueError("Pass the number of lock periods or an expiration MayaDT; not both.") # Select stake to divide from local cache try: current_stake = self.stakes[stake_index] except KeyError: if len(self.stakes): message = f"Cannot divide stake - No stake exists with index {stake_index}." else: message = "Cannot divide stake - There are no active stakes." raise Stake.StakingError(message) # Calculate stake duration in periods if expiration: additional_periods = datetime_to_period(datetime=expiration) - current_stake.end_period if additional_periods <= 0: raise Stake.StakingError(f"New expiration {expiration} must be at least 1 period from the " f"current stake's end period ({current_stake.end_period}).") # Do it already! modified_stake, new_stake = current_stake.divide(target_value=target_value, additional_periods=additional_periods) # Update staking cache self.__read_stakes() return modified_stake, new_stake
def initialize_stake(self, amount: NU, lock_periods: int = None, expiration: maya.MayaDT = None, entire_balance: bool = False) -> Stake: """Create a new stake.""" # # Duration # if lock_periods and expiration: raise ValueError( "Pass the number of lock periods or an expiration MayaDT; not both." ) if expiration: lock_periods = calculate_period_duration(future_time=expiration) # # Value # if entire_balance and amount: raise ValueError("Specify an amount or entire balance, not both") if entire_balance: amount = self.token_balance if not self.token_balance >= amount: raise self.MinerError( f"Insufficient token balance ({self.token_agent}) for new stake initialization of {amount}" ) # Ensure the new stake will not exceed the staking limit if (self.current_stake + amount) > self.economics.maximum_allowed_locked: raise Stake.StakingError( f"Cannot divide stake - Maximum stake value exceeded with a target value of {amount}." ) # # Stake # # Write to blockchain new_stake = Stake.initialize_stake(miner=self, amount=amount, lock_periods=lock_periods) self.__read_stakes() # Update local staking cache return new_stake
def initialize_stake(self, amount: NU, lock_periods: int = None, expiration: maya.MayaDT = None, entire_balance: bool = False) -> Stake: """Create a new stake.""" # Duration if lock_periods and expiration: raise ValueError( "Pass the number of lock periods or an expiration MayaDT; not both." ) if expiration: lock_periods = calculate_period_duration( future_time=expiration, seconds_per_period=self.economics.seconds_per_period) # Value if entire_balance and amount: raise ValueError("Specify an amount or entire balance, not both") if entire_balance: amount = self.token_balance if not self.token_balance >= amount: raise self.InsufficientTokens( f"Insufficient token balance ({self.token_agent}) " f"for new stake initialization of {amount}") # Ensure the new stake will not exceed the staking limit if (self.current_stake + amount) > self.economics.maximum_allowed_locked: raise Stake.StakingError( f"Cannot initialize stake - " f"Maximum stake value exceeded for {self.checksum_address} " f"with a target value of {amount}.") # Write to blockchain new_stake = Stake.initialize_stake(staker=self, amount=amount, lock_periods=lock_periods) # Update staking cache element self.stakes.refresh() return new_stake
def divide_stake( self, address: str, index: int, value: NU, duration: int, password: str = None, ): staker = self.get_active_staker(address=address) if not staker.is_staking: raise Stake.StakingError( f"{staker.checksum_address} has no published stakes.") self.attach_transacting_power(checksum_address=staker.checksum_address, password=password) result = staker.divide_stake(stake_index=index, additional_periods=duration, target_value=value) # Save results to disk self.to_configuration_file(override=True) return result