def __init__(self, checksum_address: str, rate: int = None, duration_periods: int = None, first_period_reward: int = None, *args, **kwargs): """ :param policy_agent: A policy agent with the blockchain attached; If not passed, a default policy agent and blockchain connection will be created from default values. """ super().__init__(checksum_address=checksum_address, *args, **kwargs) # From defaults self.staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=self.registry) self.policy_agent = ContractAgency.get_agent(PolicyManagerAgent, registry=self.registry) self.economics = TokenEconomicsFactory.get_economics( registry=self.registry) self.rate = rate self.duration_periods = duration_periods self.first_period_reward = first_period_reward policy_value_specified = self.rate and self.first_period_reward if policy_value_specified and self.first_period_reward >= self.rate: raise ValueError( f"Policy rate of ({self.rate}) per period must be greater " f"than the first period rate of ({self.first_period_reward})")
def confirm_activity(general_config, character_options, config_file): """ Manually confirm-activity for the current period. """ emitter = _setup_emitter(general_config, character_options.config_options.worker_address) _pre_launch_warnings(emitter, dev=character_options.config_options.dev, force=None) _, URSULA = character_options.create_character(emitter, config_file, general_config.json_ipc, load_seednodes=False) confirmed_period = URSULA.staking_agent.get_current_period() + 1 click.echo(f"Confirming activity for period {confirmed_period}", color='blue') receipt = URSULA.confirm_activity() economics = TokenEconomicsFactory.get_economics(registry=URSULA.registry) date = datetime_at_period(period=confirmed_period, seconds_per_period=economics.seconds_per_period) # TODO: Double-check dates here emitter.echo( f'\nActivity confirmed for period #{confirmed_period} ' f'(starting at {date})', bold=True, color='blue') painting.paint_receipt_summary( emitter=emitter, receipt=receipt, chain_name=URSULA.staking_agent.blockchain.client.chain_name)
def __init__(self, is_me: bool, individual_allocation: IndividualAllocationRegistry = None, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.log = Logger("staker") self.is_me = is_me self.__worker_address = None # Blockchain self.policy_agent = ContractAgency.get_agent(PolicyManagerAgent, registry=self.registry) # type: PolicyManagerAgent self.staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=self.registry) # type: StakingEscrowAgent self.economics = TokenEconomicsFactory.get_economics(registry=self.registry) # Staking via contract self.individual_allocation = individual_allocation if self.individual_allocation: self.beneficiary_address = individual_allocation.beneficiary_address self.checksum_address = individual_allocation.contract_address self.preallocation_escrow_agent = PreallocationEscrowAgent(registry=self.registry, allocation_registry=self.individual_allocation, beneficiary=self.beneficiary_address) else: self.beneficiary_address = None self.preallocation_escrow_agent = None # Check stakes self.stakes = StakeList(registry=self.registry, checksum_address=self.checksum_address)
def __init__(self, db_filepath: str, rest_host: str, rest_port: int, client_password: str = None, crash_on_error: bool = False, distribute_ether: bool = True, registry: BaseContractRegistry = None, *args, **kwargs): # Character super().__init__(registry=registry, *args, **kwargs) self.log = Logger(f"felix-{self.checksum_address[-6::]}") # Network self.rest_port = rest_port self.rest_host = rest_host self.rest_app = NOT_RUNNING self.crash_on_error = crash_on_error # Database self.db_filepath = db_filepath self.db = NO_DATABASE_AVAILABLE self.db_engine = create_engine(f'sqlite:///{self.db_filepath}', convert_unicode=True) # Blockchain transacting_power = TransactingPower(password=client_password, account=self.checksum_address) self._crypto_power.consume_power_up(transacting_power) self.token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=registry) self.blockchain = self.token_agent.blockchain self.reserved_addresses = [ self.checksum_address, BlockchainInterface.NULL_ADDRESS ] # Update reserved addresses with deployed contracts existing_entries = list(registry.enrolled_addresses) self.reserved_addresses.extend(existing_entries) # Distribution self.__distributed = 0 # Track NU Output self.__airdrop = 0 # Track Batch self.__disbursement = 0 # Track Quantity self._distribution_task = LoopingCall(f=self.airdrop_tokens) self._distribution_task.clock = self._CLOCK self.start_time = NOT_RUNNING self.economics = TokenEconomicsFactory.get_economics(registry=registry) self.MAXIMUM_DISBURSEMENT = self.economics.maximum_allowed_locked self.INITIAL_DISBURSEMENT = self.economics.minimum_allowed_locked * 3 # Optionally send ether with each token transaction self.distribute_ether = distribute_ether # Banner self.log.info(FELIX_BANNER.format(self.checksum_address))
def _learn_about_nodes_contract_info(self): agent = self.staking_agent block_time = agent.blockchain.client.w3.eth.getBlock('latest').timestamp # precision in seconds current_period = agent.get_current_period() nodes_dict = self.known_nodes.abridged_nodes_dict() self.log.info(f'Processing {len(nodes_dict)} nodes at ' f'{MayaDT(epoch=block_time)} | Period {current_period}') data = [] for staker_address in nodes_dict: worker = agent.get_worker_from_staker(staker_address) stake = agent.owned_tokens(staker_address) staked_nu_tokens = float(NU.from_nunits(stake).to_tokens()) locked_nu_tokens = float(NU.from_nunits(agent.get_locked_tokens( staker_address=staker_address)).to_tokens()) economics = TokenEconomicsFactory.get_economics(registry=self.registry) stakes = StakeList(checksum_address=staker_address, registry=self.registry) stakes.refresh() # store dates as floats for comparison purposes start_date = datetime_at_period(stakes.initial_period, seconds_per_period=economics.seconds_per_period).datetime().timestamp() end_date = datetime_at_period(stakes.terminal_period, seconds_per_period=economics.seconds_per_period).datetime().timestamp() last_confirmed_period = agent.get_last_active_period(staker_address) # TODO: do we need to worry about how much information is in memory if number of nodes is # large i.e. should I check for size of data and write within loop if too big data.append(self.BLOCKCHAIN_DB_LINE_PROTOCOL.format( measurement=self.BLOCKCHAIN_DB_MEASUREMENT, staker_address=staker_address, worker_address=worker, start_date=start_date, end_date=end_date, stake=staked_nu_tokens, locked_stake=locked_nu_tokens, current_period=current_period, last_confirmed_period=last_confirmed_period, timestamp=block_time )) if not self._blockchain_db_client.write_points(data, database=self.BLOCKCHAIN_DB_NAME, time_precision='s', batch_size=10000, protocol='line'): # TODO: what do we do here self.log.warn(f'Unable to write to database {self.BLOCKCHAIN_DB_NAME} at ' f'{MayaDT(epoch=block_time)} | Period {current_period}')
def __init__(self, is_me: bool, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.log = Logger("staker") self.is_me = is_me self.__worker_address = None # Blockchain self.policy_agent = ContractAgency.get_agent(PolicyManagerAgent, registry=self.registry) self.staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=self.registry) self.economics = TokenEconomicsFactory.get_economics(registry=self.registry) self.stakes = StakeList(registry=self.registry, checksum_address=self.checksum_address)
def __init__(self, registry: BaseContractRegistry, checksum_address: str = None, *args, **kwargs): super().__init__(*args, **kwargs) self.log = Logger('stake-tracker') self.staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=registry) from nucypher.blockchain.economics import TokenEconomicsFactory self.economics = TokenEconomicsFactory.get_economics(registry=registry) self.__initial_period = NOT_STAKING self.__terminal_period = NOT_STAKING # "load-in": Read on-chain stakes # Allow stake tracker to be initialized as an empty collection. if checksum_address: if not is_checksum_address(checksum_address): raise ValueError(f'{checksum_address} is not a valid EIP-55 checksum address') self.checksum_address = checksum_address self.__updated = None