From 8c11576c4005d4a861d2ec95b396e35c2c933c65 Mon Sep 17 00:00:00 2001 From: Kieran Prasch Date: Sat, 8 Jun 2019 11:58:02 -0700 Subject: [PATCH] Introduce StakeHolder --- nucypher/blockchain/eth/actors.py | 81 +++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/nucypher/blockchain/eth/actors.py b/nucypher/blockchain/eth/actors.py index 845b46295..3e4b38022 100644 --- a/nucypher/blockchain/eth/actors.py +++ b/nucypher/blockchain/eth/actors.py @@ -53,6 +53,7 @@ from nucypher.blockchain.eth.interfaces import BlockchainInterface from nucypher.blockchain.eth.registry import AllocationRegistry from nucypher.blockchain.eth.token import NU, Stake, StakeTracker from nucypher.blockchain.eth.utils import datetime_to_period, calculate_period_duration +from nucypher.config.base import BaseConfiguration from nucypher.config.constants import DEFAULT_CONFIG_ROOT from nucypher.crypto.powers import TransactingPower @@ -656,3 +657,83 @@ class Investigator(NucypherTokenActor): receipt = self.adjudicator_agent.evaluate_cfrag(evidence=evidence, sender_address=self.checksum_address) return receipt + + +class StakeHolder(BaseConfiguration): + + def __init__(self, + blockchain: BlockchainInterface = None, + staking_agent: StakingEscrowAgent = None, + trezor: bool = False, + *args, **kwargs): + + if not staking_agent: + staking_agent = StakingEscrowAgent(blockchain=blockchain) + + self.staking_agent = staking_agent + self.blockchain = staking_agent.blockchain + + self.trezor = trezor + self.device = NO_STAKING_DEVICE + self.setup_device() + + self.__accounts = list() + self.__stakers = dict() + + super().__init__(*args, **kwargs) + + def static_payload(self) -> dict: + payload = dict(trezor=self.trezor) + return payload + + def setup_device(self) -> None: + device = NO_STAKING_DEVICE + if self.trezor: + device = NotImplemented # Trezor() + self.device = device + + def add_account(self, address: str) -> None: + self.blockchain.interface.client.unlock_account(address=address) + self.__accounts.append(address) + + def get_accounts(self): + if self.device is not NO_STAKING_DEVICE: + self.__accounts.extend(self.device.accounts) + + def get_stakers(self) -> None: + for account in self.__accounts: + staker = Staker(is_me=True, checksum_address=account) + self.__stakers[account] = staker + + def get_staker(self, address: str) -> Staker: + try: + staker = self.__stakers[address] + except KeyError: + if address not in self.__accounts: + raise RuntimeError(f"Unknown or locked account {address}") + staker = Staker(is_me=True, checksum_address=address) + return staker + + def set_worker(self, index: int, worker_address: str): + stake = self.__stakers[index] + result = self.staking_agent.set_worker(staker_address=stake.owner_address, worker_address=worker_address) + return result + + def initialize_stake(self, address: str, amount: NU, duration: int): + staker = self.get_staker(address=address) + new_stake = Stake.initialize_stake(staker=staker, amount=amount) + return new_stake + + def divide_stake(self, address: str, index: int): + + try: + staker = self.__stakers[address] + except KeyError: + raise RuntimeError(f"No active stakes for {address}") + + try: + stake = staker.stakes[index] + except IndexError: + raise + + stake.divide(target_value=0)