Blockchain make arrangement lock periods, and consideration

pull/330/head
Kieran Prasch 2018-06-07 11:57:03 -07:00
parent a0681c78d7
commit 820f41bdc0
6 changed files with 38 additions and 42 deletions

View File

@ -311,12 +311,12 @@ class PolicyAuthor(NucypherTokenActor):
txhash = arrangement.revoke()
return txhash
def recruit(self, quantity: int, **options) -> List[Miner]:
def recruit(self, quantity: int, **options) -> Generator[Miner, None, None]:
"""Uses sampling logic to gather miners from the blockchain"""
miner_addresses = self.policy_agent.miner_agent.sample(quantity=quantity, **options)
miners = [Miner(ether_address=address, miner_agent=self.miner_agent) for address in miner_addresses]
return miners
for address in miner_addresses:
miner = Miner(ether_address=address, miner_agent=self.miner_agent)
yield miner
def create_policy(self, *args, **kwargs):
from nucypher.blockchain.eth.policies import BlockchainPolicy

View File

@ -1,4 +1,5 @@
import math
from typing import List, Set
import maya
from constant_sorrow import constants
@ -7,6 +8,7 @@ from nucypher.blockchain.eth.actors import PolicyAuthor
from nucypher.blockchain.eth.actors import Miner
from nucypher.blockchain.eth.agents import MinerAgent
from nucypher.characters import Ursula
from nucypher.policy.models import Arrangement, Policy
@ -95,23 +97,31 @@ class BlockchainPolicy(Policy):
return arrangement
def make_arrangements(self, network_middleware, quantity: int,
deposit: int, expiration: maya.MayaDT,
federated_only=False) -> None:
deposit: int, expiration: maya.MayaDT, ursulas: Set[Ursula]=None) -> None:
"""
Create and consider n Arangement objects from sampled miners.
"""
try:
sampled_miners = self.alice.recruit(quantity=quantity or self.n)
except MinerAgent.NotEnoughMiners:
raise # TODO
for miner in sampled_miners: # TODO:
if ursulas is not None:
# if len(ursulas) < self.n:
# raise Exception # TODO: Validate ursulas
pass
else:
try:
sampled_miners = self.alice.recruit(quantity=quantity or self.n)
except MinerAgent.NotEnoughMiners:
raise # TODO
else:
ursulas = (Ursula.from_miner(miner, is_me=False) for miner in sampled_miners)
for ursula in ursulas:
delta = expiration - maya.now()
hours = delta.seconds / 60 / 60
hours = (delta.total_seconds() / 60) / 60
periods = int(math.ceil(hours / int(constants.HOURS_PER_PERIOD)))
blockchain_arrangement = BlockchainArrangement(author=self.alice, miner=miner,
blockchain_arrangement = BlockchainArrangement(author=self.alice, miner=ursula,
value=deposit, lock_periods=periods,
expiration=expiration, hrac=self.hrac)

View File

@ -653,13 +653,8 @@ class Ursula(Character, ProxyRESTServer, Miner):
return self._rest_app
@classmethod
def from_config(cls, config: CharacterConfiguration) -> 'Ursula':
"""TODO"""
# Use BlockchainConfig to default to the first wallet address
wallet_address = config.blockchain.wallet_addresses[0]
instance = cls(ether_address=wallet_address)
def from_miner(cls, miner, *args, **kwargs):
instance = cls(miner_agent=miner.miner_agent, ether_address=miner.ether_address, *args, **kwargs)
return instance
@classmethod
@ -712,7 +707,7 @@ class Ursula(Character, ProxyRESTServer, Miner):
value = self.interface_info_with_metadata()
setter = self.dht_server.set(key=ursula_id, value=value)
self.publish_data(ursula_id)
self.publish_datastore(ursula_id)
loop = asyncio.get_event_loop()
loop.run_until_complete(setter)

View File

@ -2,7 +2,7 @@ import binascii
import uuid
from abc import ABC, abstractmethod
from collections import OrderedDict
from typing import Generator
from typing import Generator, List
import maya
import msgpack
@ -113,7 +113,6 @@ class Policy(ABC):
Once Alice has secured agreement with n Ursulas to enact a Policy, she sends each a KFrag,
and generates a TreasureMap for the Policy, recording which Ursulas got a KFrag.
"""
_ursula = None
def __init__(self, alice, label, bob=None, kfrags=(constants.UNKNOWN_KFRAG,),
public_key=None, m=None, alices_signature=constants.NOT_SIGNED):
@ -148,18 +147,6 @@ class Policy(ABC):
def n(self):
return len(self.kfrags)
@property
def ursula(self):
if not self._ursula:
raise Ursula.NotFound
else:
return self._ursula
@ursula.setter
def ursula(self, ursula_object):
self.alice.learn_about_actor(ursula_object)
self._ursula = ursula_object
def hrac(self):
"""
The "hashed resource authentication code".
@ -258,7 +245,7 @@ class Policy(ABC):
self.publish()
def consider_arrangement(self, network_middleware, arrangement):
ursula, negotiation_response = network_middleware.consider_arrangement(ursula=self.ursula,
ursula, negotiation_response = network_middleware.consider_arrangement(ursula=arrangement.ursula,
arrangement=arrangement)
# TODO: check out the response: need to assess the result and see if we're actually good to go.
@ -271,14 +258,18 @@ class Policy(ABC):
@abstractmethod
def make_arrangements(self, network_middleware, quantity: int,
deposit: int, expiration: maya.MayaDT) -> None:
deposit: int, expiration: maya.MayaDT, ursulas: List[Ursula]=None) -> None:
"""
Create and consider n Arangement objects.
"""
ursulas = NotImplemented
if not ursulas:
ursulas = NotImplemented
for ursula in ursulas:
arrangement = Arrangement(alice=NotImplemented,
ursula=ursula, hrac=self.hrac, expiration=expiration)
ursula=ursula,
hrac=self.hrac,
expiration=expiration)
self.consider_arrangement(network_middleware=network_middleware,
arrangement=arrangement)

View File

@ -65,7 +65,7 @@ class TestMiner:
# Publish Miner IDs to the DHT
some_data = os.urandom(32)
_txhash = miner.publish_data(some_data)
_txhash = miner.publish_datastore(some_data)
# Fetch the miner Ids
stored_miner_ids = miner.fetch_data()
@ -75,7 +75,7 @@ class TestMiner:
# Repeat, with another miner ID
another_mock_miner_id = os.urandom(32)
_txhash = miner.publish_data(another_mock_miner_id)
_txhash = miner.publish_datastore(another_mock_miner_id)
stored_miner_ids = miner.fetch_data()

View File

@ -32,7 +32,7 @@ def make_ursulas(ether_addresses: list, ursula_starting_port: int, miners=False)
_ursulas = []
for _counter, ether_address in enumerate(ether_addresses):
port = ursula_starting_port + _counter
ursula = Ursula(ether_address=ether_address, dht_port=port, db_name="test-{}".format(port),
ursula = Ursula(is_me=True, ether_address=ether_address, dht_port=port, db_name="test-{}".format(port),
ip_address="127.0.0.1", rest_port=port + 100)
class MockDatastoreThreadPool(object):