diff --git a/cli/demos/finnegans-wake-demo.py b/cli/demos/finnegans-wake-demo.py deleted file mode 100644 index c0ce2a615..000000000 --- a/cli/demos/finnegans-wake-demo.py +++ /dev/null @@ -1,165 +0,0 @@ -# This is an example of Alice setting a Policy on the NuCypher network. -# In this example, Alice uses n=1, which is almost always a bad idea. Don't do it. - -# WIP w/ hendrix@3.0.0 -import sys - -import click -import datetime -import maya - -from nucypher.blockchain.eth.chains import Blockchain -from nucypher.characters.lawful import Alice, Bob -from nucypher.characters.lawful import Ursula -from nucypher.config.characters import UrsulaConfiguration, AliceConfiguration, BobConfiguration -from nucypher.data_sources import DataSource -from nucypher.network.middleware import RestMiddleware -from umbral.keys import UmbralPublicKey - - -@click.command() -@click.option('--federated-only', is_flag=True) -def run_demo(federated_only): - - ############################################## - # This is already running in another process. - ############################################## - - if federated_only is False: - BLOCKCHAIN = Blockchain.connect() - - ######### - # Alice # - ######### - - ALICE = AliceConfiguration(federated_only=federated_only, - network_middleware=RestMiddleware(), - start_learning_now=True, - load_metadata=True, - abort_on_learning_error=True, - learn_on_same_thread=False).produce() # TODO: 289 - - # Here are our Policy details. - policy_end_datetime = maya.now() + datetime.timedelta(days=5) - m = 2 - n = 3 - label = b"secret/files/and/stuff" - - # Alice grants to Bob. - BOB = BobConfiguration(federated_only=federated_only, - learn_on_same_thread=False, - start_learning_now=True).produce() - - ALICE.start_learning_loop(now=True) - policy = ALICE.grant(BOB, - label, - m=m, - n=n, - expiration=policy_end_datetime) - - # Alice puts her public key somewhere for Bob to find later... - alices_pubkey_bytes_saved_for_posterity = bytes(ALICE.stamp) - - # ...and then disappears from the internet. - del ALICE - # (this is optional of course - she may wish to remain in order to create - # new policies in the future. The point is - she is no longer obligated. - - ##################### - # some time passes. # - # ... # - # # - # ... # - # And now for Bob. # - ##################### - - # Bob wants to join the policy so that he can receive any future - # data shared on it. - # He needs a few pieces of knowledge to do that. - BOB.join_policy(label, # The label - he needs to know what data he's after. - alices_pubkey_bytes_saved_for_posterity, # To verify the signature, he'll need Alice's public key. - # He can also bootstrap himself onto the network more quickly - # by providing a list of known nodes at this time. - # node_list=[("localhost", 3601)] - ) - - # Now that Bob has joined the Policy, let's show how DataSources - # can share data with the members of this Policy and then how Bob retrieves it. - finnegans_wake = open(sys.argv[1], 'rb') - - # We'll also keep track of some metadata to gauge performance. - # You can safely ignore from here until... - ################################################################################ - - start_time = datetime.datetime.now() - - for counter, plaintext in enumerate(finnegans_wake): - if counter % 20 == 0: - now_time = datetime.datetime.now() - time_delta = now_time - start_time - seconds = time_delta.total_seconds() - print("********************************") - print("Performed {} PREs".format(counter)) - print("Elapsed: {}".format(time_delta.total_seconds())) - print("PREs per second: {}".format(counter / seconds)) - print("********************************") - - ################################################################################ - # ...here. OK, pay attention again. - # Now it's time for... - - ##################### - # Using DataSources # - ##################### - - # Now Alice has set a Policy and Bob has joined it. - # You're ready to make some DataSources and encrypt for Bob. - - # It may also be helpful to imagine that you have multiple Bobs, - # multiple Labels, or both. - - # First we make a DataSource for this policy. - data_source = DataSource(policy_pubkey_enc=policy.public_key) - - # Here's how we generate a MessageKit for the Policy. We also get a signature - # here, which can be passed via a side-channel (or posted somewhere public as - # testimony) and verified if desired. In this case, the plaintext is a - # single passage from James Joyce's Finnegan's Wake. - # The matter of whether encryption makes the passage more or less readable - # is left to the reader to determine. - message_kit, _signature = data_source.encapsulate_single_message(plaintext) - - # The DataSource will want to be able to be verified by Bob, so it leaves - # its Public Key somewhere. - data_source_public_key = bytes(data_source.stamp) - - # It can save the MessageKit somewhere (IPFS, etc) and then it too can - # choose to disappear (although it may also opt to continue transmitting - # as many messages as may be appropriate). - del data_source - - ############### - # Back to Bob # - ############### - - # Bob needs to reconstruct the DataSource. - datasource_as_understood_by_bob = DataSource.from_public_keys( - policy_public_key=policy.public_key, - datasource_public_key=data_source_public_key, - label=label - ) - - # Now Bob can retrieve the original message. He just needs the MessageKit - # and the DataSource which produced it. - alice_pubkey_restored_from_ancient_scroll = UmbralPublicKey.from_bytes(alices_pubkey_bytes_saved_for_posterity) - delivered_cleartexts = BOB.retrieve(message_kit=message_kit, - data_source=datasource_as_understood_by_bob, - alice_verifying_key=alice_pubkey_restored_from_ancient_scroll) - - # We show that indeed this is the passage originally encrypted by the DataSource. - assert plaintext == delivered_cleartexts[0] - print("Retrieved: {}".format(delivered_cleartexts[0])) - - -if __name__ == "__main__": - run_demo() diff --git a/examples/finnegans-wake-federated.py b/examples/finnegans-wake-federated.py index f4eafdacf..69ad32dc0 100644 --- a/examples/finnegans-wake-federated.py +++ b/examples/finnegans-wake-federated.py @@ -52,12 +52,12 @@ URSULA.save_certificate_to_disk(CERTIFICATE_DIR) ######### -ALICE = AliceConfiguration(network_middleware=RestMiddleware(), - known_nodes=(URSULA,), - federated_only=True, - always_be_learning=True, - known_certificates_dir=CERTIFICATE_DIR, - ) # TODO: 289 +ALICE = Alice(network_middleware=RestMiddleware(), + known_nodes=(URSULA,), + federated_only=True, + always_be_learning=True, + known_certificates_dir=CERTIFICATE_DIR, + ) # Here are our Policy details. policy_end_datetime = maya.now() + datetime.timedelta(days=5) diff --git a/nucypher/characters/lawful.py b/nucypher/characters/lawful.py index 27defddb7..427f06b4c 100644 --- a/nucypher/characters/lawful.py +++ b/nucypher/characters/lawful.py @@ -241,7 +241,7 @@ class Bob(Character): if not self.known_nodes and not self._learning_task.running: # Quick sanity check - if we don't know of *any* Ursulas, and we have no # plans to learn about any more, than this function will surely fail. - raise Ursula.NotEnoughUrsulas + raise self.NotEnoughTeachers treasure_map = self.get_treasure_map_from_known_ursulas(self.network_middleware, map_id) diff --git a/nucypher/crypto/api.py b/nucypher/crypto/api.py index 3fd43b180..732fb1967 100644 --- a/nucypher/crypto/api.py +++ b/nucypher/crypto/api.py @@ -116,7 +116,7 @@ def ecdsa_verify(message: bytes, def _save_tls_certificate(certificate: Certificate, full_filepath: str, - force: bool = True, # TODO + force: bool = True, # TODO: Make configurable, or set to False by default. ) -> str: if force is False and os.path.isfile(full_filepath): raise FileExistsError('A TLS certificate already exists at {}.'.format(full_filepath)) diff --git a/nucypher/network/nodes.py b/nucypher/network/nodes.py index 867582953..82a068ef9 100644 --- a/nucypher/network/nodes.py +++ b/nucypher/network/nodes.py @@ -29,10 +29,6 @@ class VerifiableNode: self.certificate_filepath = certificate_filepath self._interface_signature_object = interface_signature - # TODO: This gets messy when it is None - # (although it being None is actually reasonable in some cases, at least for testing). - # Let's make this a method instead that inspects the TLSHostingPower (similar to get_deployer()). - class InvalidNode(SuspiciousActivity): """ Raised when a node has an invalid characteristic - stamp, interface, or address. @@ -68,7 +64,10 @@ class VerifiableNode: self.verified_stamp = True return True elif self.federated_only and signature is constants.NOT_SIGNED: - raise self.WrongMode("This node can't be verified in this manner, but is OK to use in federated mode if you have reason to believe it is trustworthy.") + message = "This node can't be verified in this manner, " \ + "but is OK to use in federated mode if you" \ + " have reason to believe it is trustworthy." + raise self.WrongMode(message) else: raise self.InvalidNode diff --git a/tests/network/test_network_actors.py b/tests/network/test_network_actors.py index 16e82c49e..5bf639a5d 100644 --- a/tests/network/test_network_actors.py +++ b/tests/network/test_network_actors.py @@ -83,7 +83,7 @@ def test_bob_can_retreive_the_treasure_map_and_decrypt_it(enacted_federated_poli # through a side-channel with Alice. # If Bob doesn't know about any Ursulas, he can't find the TreasureMap via the REST swarm: - with pytest.raises(Ursula.NotEnoughUrsulas): + with pytest.raises(bob.NotEnoughTeachers): treasure_map_from_wire = bob.get_treasure_map(enacted_federated_policy.alice.stamp, enacted_federated_policy.label)