def test_split_signature_from_arbitrary_bytes(): how_many_bytes = 10 signature = Signature.from_bytes(secure_random(64)) some_bytes = secure_random(how_many_bytes) splitter = BytestringSplitter(Signature, (bytes, how_many_bytes)) rebuilt_signature, rebuilt_bytes = splitter(signature + some_bytes)
def test_secure_random(self): rand1 = api.secure_random(10) rand2 = api.secure_random(10) self.assertNotEqual(rand1, rand2) self.assertEqual(bytes, type(rand1)) self.assertEqual(bytes, type(rand2)) self.assertEqual(10, len(rand1)) self.assertEqual(10, len(rand2))
def test_trying_to_extract_too_many_bytes_raises_typeerror(): how_many_bytes = 10 too_many_bytes = 11 signature = Signature.from_bytes(secure_random(64)) some_bytes = secure_random(how_many_bytes) splitter = BytestringSplitter(Signature, (bytes, too_many_bytes)) with pytest.raises(ValueError): rebuilt_signature, rebuilt_bytes = splitter(signature + some_bytes, return_remainder=True)
def test_split_two_signatures(): """ We make two random Signatures and concat them. Then split them and show that we got the proper result. """ sig1 = Signature.from_bytes(secure_random(64)) sig2 = Signature.from_bytes(secure_random(64)) sigs_concatted = sig1 + sig2 two_signature_splitter = BytestringSplitter(Signature, Signature) rebuilt_sig1, rebuilt_sig2 = two_signature_splitter(sigs_concatted) assert (sig1, sig2) == (rebuilt_sig1, rebuilt_sig2)
def __init__(self, alice: Alice, expiration: maya.MayaDT, ursula: Ursula = None, arrangement_id: bytes = None, kfrag: KFrag = UNKNOWN_KFRAG) -> None: """ :param value: Funds which will pay for the timeframe of this Arrangement (not the actual re-encryptions); a portion will be locked for each Ursula that accepts. :param expiration: The moment which Alice wants the Arrangement to end. Other params are hopefully self-evident. """ if arrangement_id: if len(arrangement_id) != self.ID_LENGTH: raise ValueError( f"Arrangement ID must be of length {self.ID_LENGTH}.") self.id = arrangement_id else: self.id = secure_random(self.ID_LENGTH) self.expiration = expiration self.alice = alice self.status = None """ These will normally not be set if Alice is drawing up this arrangement - she hasn't assigned a kfrag yet (because she doesn't know if this Arrangement will be accepted). She doesn't have an Ursula, for the same reason. """ self.kfrag = kfrag self.ursula = ursula
def __init__(self, alice, expiration, ursula=None, id=None, kfrag=constants.UNKNOWN_KFRAG, value=None, alices_signature=None): """ :param deposit: Funds which will pay for the timeframe of this Arrangement (not the actual re-encryptions); a portion will be locked for each Ursula that accepts. :param expiration: The moment which Alice wants the Arrangement to end. Other params are hopefully self-evident. """ self.id = id or secure_random(self.ID_LENGTH) self.expiration = expiration self.alice = alice self.uuid = uuid.uuid4() self.value = None """ These will normally not be set if Alice is drawing up this arrangement - she hasn't assigned a kfrag yet (because she doesn't know if this Arrangement will be accepted). She doesn't have an Ursula, for the same reason. """ self.kfrag = kfrag self.ursula = ursula
def make_decentralized_ursulas(ursula_config: UrsulaConfiguration, ether_addresses: Union[list, int], stake: bool = False, know_each_other: bool = True, **ursula_overrides) -> Set[Ursula]: # Alternately accepts an int of the quantity of ursulas to make if isinstance(ether_addresses, int): ether_addresses = [ to_checksum_address(secure_random(20)) for _ in range(ether_addresses) ] if not TEST_KNOWN_URSULAS_CACHE: starting_port = TEST_URSULA_STARTING_PORT else: starting_port = max(TEST_KNOWN_URSULAS_CACHE.keys()) + 1 ursulas = set() for port, checksum_address in enumerate(ether_addresses, start=starting_port): ursula = ursula_config.produce(checksum_address=checksum_address, db_name="test-{}".format(port), rest_port=port + 100, **ursula_overrides) if stake is True: min_stake, balance = int( constants.MIN_ALLOWED_LOCKED), ursula.token_balance amount = random.randint(min_stake, balance) # for a random lock duration min_locktime, max_locktime = int( constants.MIN_LOCKED_PERIODS), int( constants.MAX_MINTING_PERIODS) periods = random.randint(min_locktime, max_locktime) ursula.initialize_stake(amount=amount, lock_periods=periods) ursulas.add(ursula) # Store this Ursula in our global cache. port = ursula.rest_information()[0].port TEST_KNOWN_URSULAS_CACHE[port] = ursula if know_each_other: for ursula_to_teach in ursulas: # Add other Ursulas as known nodes. for ursula_to_learn_about in ursulas: ursula_to_teach.remember_node(ursula_to_learn_about) return ursulas
def make_decentralized_ursulas(ursula_config: UrsulaConfiguration, ether_addresses: Union[list, int], stake: bool = False, know_each_other: bool = True, economics: TokenEconomics = None, **ursula_overrides) -> List[Ursula]: if not economics: economics = TokenEconomics() # Alternately accepts an int of the quantity of ursulas to make if isinstance(ether_addresses, int): ether_addresses = [to_checksum_address(secure_random(20)) for _ in range(ether_addresses)] if not MOCK_KNOWN_URSULAS_CACHE: starting_port = MOCK_URSULA_STARTING_PORT else: starting_port = max(MOCK_KNOWN_URSULAS_CACHE.keys()) + 1 ursulas = list() for port, checksum_address in enumerate(ether_addresses, start=starting_port): ursula = ursula_config.produce(checksum_public_address=checksum_address, db_filepath=MOCK_URSULA_DB_FILEPATH, rest_port=port + 100, **ursula_overrides) if stake is True: min_stake, balance = economics.minimum_allowed_locked, ursula.token_balance amount = random.randint(min_stake, balance) # for a random lock duration min_locktime, max_locktime = economics.minimum_locked_periods, economics.maximum_locked_periods periods = random.randint(min_locktime, max_locktime) ursula.initialize_stake(amount=amount, lock_periods=periods) ursulas.append(ursula) # Store this Ursula in our global cache. port = ursula.rest_information()[0].port MOCK_KNOWN_URSULAS_CACHE[port] = ursula if know_each_other: for ursula_to_teach in ursulas: # Add other Ursulas as known nodes. for ursula_to_learn_about in ursulas: ursula_to_teach.remember_node(ursula_to_learn_about) return ursulas
def attach_server(self, ksize=20, alpha=3, id=None, storage=None, *args, **kwargs): # TODO: Network-wide deterministic ID generation (ie, auction or # whatever) See #136. if not id: id = digest(secure_random(32)) super().attach_server(ksize, alpha, id, storage) self.attach_rest_server(db_name=self.db_name)
def from_alice(cls, alice: Alice, expiration: maya.MayaDT) -> 'Arrangement': arrangement_id = secure_random(cls.ID_LENGTH) alice_verifying_key = alice.stamp.as_umbral_pubkey() return cls(alice_verifying_key, expiration, arrangement_id)
def make_ursulas(ether_addresses: list, miner_agent=None, miners=False, bare=False, know_each_other=True, **ursula_kwargs) -> Set[Ursula]: """ :param ether_addresses: Ethereum addresses to create ursulas with. :param ursula_starting_port: The port of the first created Ursula; subsequent Ursulas will increment the port number by 1. :param miner_agent: A miner agent instance to use when creating ursulas. :param miners: If True, create staking ursulas on the blockchain from the addresses :param bare: If True, Create an non-learning Ursula without a rest app, dht server or database attached, for testing mining functionality when network transport is not needed. "Just a miner" :return: A list of created Ursulas """ if isinstance(ether_addresses, int): ether_addresses = [to_checksum_address(secure_random(20)) for _ in range(ether_addresses)] event_loop = asyncio.get_event_loop() if not _TEST_KNOWN_URSULAS_CACHE: starting_port = constants.URSULA_PORT_SEED else: starting_port = max(_TEST_KNOWN_URSULAS_CACHE.keys()) + 1 ursulas = set() for port, ether_address in enumerate(ether_addresses, start=starting_port): if bare: ursula = Ursula(is_me=False, # do not attach dht server rest_host="localhost", # TODO: remove rest interface rest_port=port + 100, checksum_address=ether_address, always_be_learning=False, miner_agent=miner_agent, abort_on_learning_error=True, **ursula_kwargs) ursula.is_me = True # Patch to allow execution of transacting methods in tests else: federated_only = not miners if federated_only: ether_address = None ursula = Ursula(is_me=True, checksum_address=ether_address, dht_host="localhost", dht_port=port, db_name="test-{}".format(port), rest_host="localhost", rest_port=port+100, always_be_learning=False, miner_agent=miner_agent, federated_only=federated_only, **ursula_kwargs) ursula.attach_rest_server() class MockDatastoreThreadPool(object): def callInThread(self, f, *args, **kwargs): return f(*args, **kwargs) ursula.datastore_threadpool = MockDatastoreThreadPool() ursula.dht_listen() if miners is True: # TODO: 309 # stake a random amount min_stake, balance = constants.MIN_ALLOWED_LOCKED, ursula.token_balance amount = random.randint(min_stake, balance) # for a random lock duration min_locktime, max_locktime = constants.MIN_LOCKED_PERIODS, constants.MAX_MINTING_PERIODS periods = random.randint(min_locktime, max_locktime) ursula.initialize_stake(amount=amount, lock_periods=periods) else: ursula.federated_only = True ursulas.add(ursula) _TEST_KNOWN_URSULAS_CACHE[ursula.rest_interface.port] = ursula if know_each_other and not bare: for ursula_to_teach in ursulas: # Add other Ursulas as known nodes. for ursula_to_learn_about in ursulas: ursula_to_teach.remember_node(ursula_to_learn_about) event_loop.run_until_complete( ursula.dht_server.bootstrap( [("localhost", starting_port + _c) for _c in range(len(ursulas))])) ursula.publish_dht_information() return ursulas