Removes "decentralized" and "blockchain" differentiation from "federated"

pull/3030/head
Kieran Prasch 2022-11-30 12:46:51 +01:00
parent 18d3d6e0a5
commit fda5c86db2
35 changed files with 614 additions and 738 deletions

View File

@ -1102,8 +1102,10 @@ class Teacher:
return True return True
if not registry: # TODO: # 466 if not registry: # TODO: # 466
self.log.debug("No registry provided for decentralized stranger node verification - " self.log.debug(
"on-chain Staking verification will not be performed.") "No registry provided for peer verification - "
"on-chain stake verification will not be performed."
)
# This is both the stamp's client signature and interface metadata check; May raise InvalidNode # This is both the stamp's client signature and interface metadata check; May raise InvalidNode
self.validate_metadata(registry=registry, eth_provider_uri=eth_provider_uri) self.validate_metadata(registry=registry, eth_provider_uri=eth_provider_uri)

View File

@ -11,7 +11,7 @@ from nucypher.network.middleware import RestMiddleware
from nucypher.policy.reservoir import ( from nucypher.policy.reservoir import (
MergedReservoir, MergedReservoir,
PrefetchStrategy, PrefetchStrategy,
make_decentralized_staking_provider_reservoir, make_staking_provider_reservoir,
) )
from nucypher.policy.revocation import RevocationKit from nucypher.policy.revocation import RevocationKit
from nucypher.utilities.concurrency import WorkerPool from nucypher.utilities.concurrency import WorkerPool
@ -181,9 +181,11 @@ class Policy(ABC):
class BlockchainPolicy(Policy): class BlockchainPolicy(Policy):
def _make_reservoir(self, handpicked_addresses: List[ChecksumAddress]): def _make_reservoir(self, handpicked_addresses: List[ChecksumAddress]):
"""Returns a reservoir of staking nodes to create a decentralized policy.""" """Returns a reservoir of staking nodes to create a policy."""
reservoir = make_decentralized_staking_provider_reservoir(application_agent=self.publisher.application_agent, reservoir = make_staking_provider_reservoir(
include_addresses=handpicked_addresses) application_agent=self.publisher.application_agent,
include_addresses=handpicked_addresses,
)
return reservoir return reservoir

View File

@ -8,10 +8,12 @@ from nucypher.blockchain.eth.agents import (
) )
def make_decentralized_staking_provider_reservoir(application_agent: PREApplicationAgent, def make_staking_provider_reservoir(
exclude_addresses: Optional[Iterable[ChecksumAddress]] = None, application_agent: PREApplicationAgent,
include_addresses: Optional[Iterable[ChecksumAddress]] = None, exclude_addresses: Optional[Iterable[ChecksumAddress]] = None,
pagination_size: int = None): include_addresses: Optional[Iterable[ChecksumAddress]] = None,
pagination_size: int = None,
):
"""Get a sampler object containing the currently registered staking providers.""" """Get a sampler object containing the currently registered staking providers."""
# needs to not include both exclude and include addresses # needs to not include both exclude and include addresses

View File

@ -16,7 +16,7 @@ from nucypher.blockchain.eth.signers.software import Web3Signer
from nucypher.blockchain.eth.token import NU from nucypher.blockchain.eth.token import NU
from nucypher.crypto.powers import TransactingPower from nucypher.crypto.powers import TransactingPower
from nucypher.utilities.logging import Logger from nucypher.utilities.logging import Logger
from tests.utils.ursula import make_decentralized_ursulas, start_pytest_ursula_services from tests.utils.ursula import make_ursulas, start_pytest_ursula_services
logger = Logger("test-operator") logger = Logger("test-operator")
@ -35,7 +35,7 @@ def test_work_tracker(
staker, staker,
agency, agency,
application_economics, application_economics,
ursula_decentralized_test_config, ursula_test_config,
): ):
staker.initialize_stake( staker.initialize_stake(
@ -59,8 +59,8 @@ def test_work_tracker(
) )
# Make the Worker # Make the Worker
ursula = make_decentralized_ursulas( ursula = make_ursulas(
ursula_config=ursula_decentralized_test_config, ursula_config=ursula_test_config,
staking_provider_addresses=[staker.checksum_address], staking_provider_addresses=[staker.checksum_address],
operator_addresses=[worker_address], operator_addresses=[worker_address],
registry=test_registry, registry=test_registry,
@ -190,7 +190,7 @@ def test_work_tracker(
def test_ursula_operator_confirmation( def test_ursula_operator_confirmation(
ursula_decentralized_test_config, ursula_test_config,
testerchain, testerchain,
threshold_staking, threshold_staking,
agency, agency,
@ -217,7 +217,7 @@ def test_ursula_operator_confirmation(
testerchain.wait_for_receipt(tx) testerchain.wait_for_receipt(tx)
# make an ursula. # make an ursula.
blockchain_ursula = ursula_decentralized_test_config.produce( blockchain_ursula = ursula_test_config.produce(
operator_address=operator_address, rest_port=9151 operator_address=operator_address, rest_port=9151
) )
@ -252,7 +252,7 @@ def test_ursula_operator_confirmation(
@pytest_twisted.inlineCallbacks @pytest_twisted.inlineCallbacks
def test_ursula_operator_confirmation_autopilot( def test_ursula_operator_confirmation_autopilot(
mocker, mocker,
ursula_decentralized_test_config, ursula_test_config,
testerchain, testerchain,
threshold_staking, threshold_staking,
agency, agency,
@ -292,9 +292,7 @@ def test_ursula_operator_confirmation_autopilot(
) )
# Make the Operator # Make the Operator
ursula = ursula_decentralized_test_config.produce( ursula = ursula_test_config.produce(operator_address=operator2, rest_port=9151)
operator_address=operator2, rest_port=9151
)
ursula.run( ursula.run(
preflight=False, preflight=False,

View File

@ -270,14 +270,15 @@ def test_erc721_evm_condition_balanceof_evaluation(
def test_subscription_manager_is_active_policy_condition_evaluation( def test_subscription_manager_is_active_policy_condition_evaluation(
testerchain, testerchain,
enacted_blockchain_policy, enacted_policy,
subscription_manager_is_active_policy_condition, subscription_manager_is_active_policy_condition,
condition_providers condition_providers
): ):
context = { context = {":hrac": bytes(enacted_policy.hrac)} # user-defined context var
":hrac": bytes(enacted_blockchain_policy.hrac) (
} # user-defined context var condition_result,
condition_result, call_result = subscription_manager_is_active_policy_condition.verify( call_result,
) = subscription_manager_is_active_policy_condition.verify(
providers=condition_providers, **context providers=condition_providers, **context
) )
assert call_result assert call_result
@ -294,7 +295,7 @@ def test_subscription_manager_is_active_policy_condition_evaluation(
def test_subscription_manager_get_policy_policy_struct_condition_evaluation( def test_subscription_manager_get_policy_policy_struct_condition_evaluation(
testerchain, testerchain,
enacted_blockchain_policy, enacted_policy,
subscription_manager_get_policy_zeroized_policy_struct_condition, subscription_manager_get_policy_zeroized_policy_struct_condition,
condition_providers condition_providers
): ):
@ -304,7 +305,7 @@ def test_subscription_manager_get_policy_policy_struct_condition_evaluation(
NULL_ADDRESS, 0, 0, 0, NULL_ADDRESS, NULL_ADDRESS, 0, 0, 0, NULL_ADDRESS,
) )
context = { context = {
":hrac": bytes(enacted_blockchain_policy.hrac), ":hrac": bytes(enacted_policy.hrac),
":expectedPolicyStruct": zeroized_policy_struct, ":expectedPolicyStruct": zeroized_policy_struct,
} # user-defined context vars } # user-defined context vars
condition_result, call_result = subscription_manager_get_policy_zeroized_policy_struct_condition.verify( condition_result, call_result = subscription_manager_get_policy_zeroized_policy_struct_condition.verify(
@ -326,18 +327,18 @@ def test_subscription_manager_get_policy_policy_struct_condition_key_tuple_evalu
testerchain, testerchain,
agency, agency,
test_registry, test_registry,
idle_blockchain_policy, idle_policy,
enacted_blockchain_policy, enacted_policy,
condition_providers, condition_providers,
): ):
# enacted policy created from idle policy # enacted policy created from idle policy
size = len(idle_blockchain_policy.kfrags) size = len(idle_policy.kfrags)
start = idle_blockchain_policy.commencement start = idle_policy.commencement
end = idle_blockchain_policy.expiration end = idle_policy.expiration
sponsor = idle_blockchain_policy.publisher.checksum_address sponsor = idle_policy.publisher.checksum_address
context = { context = {
":hrac": bytes(enacted_blockchain_policy.hrac), ":hrac": bytes(enacted_policy.hrac),
} # user-defined context vars } # user-defined context vars
subscription_manager = ContractAgency.get_agent( subscription_manager = ContractAgency.get_agent(
SubscriptionManagerAgent, registry=test_registry SubscriptionManagerAgent, registry=test_registry
@ -446,14 +447,14 @@ def test_subscription_manager_get_policy_policy_struct_condition_key_context_var
testerchain, testerchain,
agency, agency,
test_registry, test_registry,
idle_blockchain_policy, idle_policy,
enacted_blockchain_policy, enacted_policy,
condition_providers, condition_providers,
): ):
# enacted policy created from idle policy # enacted policy created from idle policy
sponsor = idle_blockchain_policy.publisher.checksum_address sponsor = idle_policy.publisher.checksum_address
context = { context = {
":hrac": bytes(enacted_blockchain_policy.hrac), ":hrac": bytes(enacted_policy.hrac),
":sponsor": sponsor, ":sponsor": sponsor,
":sponsorIndex": 0, ":sponsorIndex": 0,
} # user-defined context vars } # user-defined context vars
@ -530,33 +531,26 @@ def test_onchain_conditions_lingo_evaluation(
assert result is True assert result is True
def test_single_retrieve_with_onchain_conditions(enacted_blockchain_policy, blockchain_bob, blockchain_ursulas): def test_single_retrieve_with_onchain_conditions(enacted_policy, bob, ursulas):
blockchain_bob.remember_node(blockchain_ursulas[0]) bob.remember_node(ursulas[0])
blockchain_bob.start_learning_loop() bob.start_learning_loop()
conditions = [ conditions = [
{'returnValueTest': {'value': '0', 'comparator': '>'}, 'method': 'timelock'}, {"returnValueTest": {"value": "0", "comparator": ">"}, "method": "timelock"},
{'operator': 'and'}, {"operator": "and"},
{"chain": TESTERCHAIN_CHAIN_ID, {
"method": "eth_getBalance", "chain": TESTERCHAIN_CHAIN_ID,
"parameters": [ "method": "eth_getBalance",
blockchain_bob.checksum_address, "parameters": [bob.checksum_address, "latest"],
"latest" "returnValueTest": {"comparator": ">=", "value": "10000000000000"},
], },
"returnValueTest": {
"comparator": ">=",
"value": "10000000000000"
}
}
] ]
messages, message_kits = make_message_kits( messages, message_kits = make_message_kits(enacted_policy.public_key, conditions)
enacted_blockchain_policy.public_key, conditions
)
policy_info_kwargs = dict( policy_info_kwargs = dict(
encrypted_treasure_map=enacted_blockchain_policy.treasure_map, encrypted_treasure_map=enacted_policy.treasure_map,
alice_verifying_key=enacted_blockchain_policy.publisher_verifying_key, alice_verifying_key=enacted_policy.publisher_verifying_key,
) )
cleartexts = blockchain_bob.retrieve_and_decrypt( cleartexts = bob.retrieve_and_decrypt(
message_kits=message_kits, message_kits=message_kits,
**policy_info_kwargs, **policy_info_kwargs,
) )

View File

@ -31,12 +31,14 @@ def check(policy, bob, ursulas):
# TODO: try to decrypt? # TODO: try to decrypt?
def test_decentralized_grant_subscription_manager(blockchain_alice, blockchain_bob, blockchain_ursulas): def test_grant_subscription_manager(alice, bob, ursulas):
payment_method = SubscriptionManagerPayment(eth_provider=TEST_ETH_PROVIDER_URI, network=TEMPORARY_DOMAIN) payment_method = SubscriptionManagerPayment(eth_provider=TEST_ETH_PROVIDER_URI, network=TEMPORARY_DOMAIN)
blockchain_alice.payment_method = payment_method alice.payment_method = payment_method
policy = blockchain_alice.grant(bob=blockchain_bob, policy = alice.grant(
label=os.urandom(16), bob=bob,
threshold=2, label=os.urandom(16),
shares=shares, threshold=2,
expiration=policy_end_datetime) shares=shares,
check(policy=policy, bob=blockchain_bob, ursulas=blockchain_ursulas) expiration=policy_end_datetime,
)
check(policy=policy, bob=bob, ursulas=ursulas)

View File

@ -10,33 +10,33 @@ from nucypher.characters.lawful import Enrico, Ursula
from nucypher.characters.unlawful import Amonia from nucypher.characters.unlawful import Amonia
@pytest.mark.skip('FIXME - DISABLED FOR TDEC ADAPTATION DEVELOPMENT') @pytest.mark.skip("FIXME - DISABLED FOR TDEC ADAPTATION DEVELOPMENT")
def test_try_to_post_free_service_by_hacking_enact(blockchain_ursulas, def test_try_to_post_free_service_by_hacking_enact(
blockchain_alice, ursulas, alice, bob, agency, testerchain
blockchain_bob, ):
agency,
testerchain):
""" """
This time we won't rely on the tabulation in Alice's enact() to catch the problem. This time we won't rely on the tabulation in Alice's enact() to catch the problem.
""" """
amonia = Amonia.from_lawful_alice(blockchain_alice) amonia = Amonia.from_lawful_alice(alice)
# Set up the policy details # Set up the policy details
shares = 3 shares = 3
policy_end_datetime = maya.now() + datetime.timedelta(days=35) policy_end_datetime = maya.now() + datetime.timedelta(days=35)
label = b"another_path" label = b"another_path"
bupkiss_policy = amonia.circumvent_safegaurds_and_grant_without_paying(bob=blockchain_bob, bupkiss_policy = amonia.circumvent_safegaurds_and_grant_without_paying(
label=label, bob=bob, label=label, threshold=2, shares=shares, expiration=policy_end_datetime
threshold=2, )
shares=shares,
expiration=policy_end_datetime)
# Enrico becomes # Enrico becomes
enrico = Enrico(policy_encrypting_key=bupkiss_policy.public_key) enrico = Enrico(policy_encrypting_key=bupkiss_policy.public_key)
plaintext = b"A crafty campaign" plaintext = b"A crafty campaign"
message_kit = enrico.encrypt_message(plaintext) message_kit = enrico.encrypt_message(plaintext)
with pytest.raises(Ursula.NotEnoughUrsulas): # Return a more descriptive request error? with pytest.raises(
blockchain_bob.retrieve_and_decrypt([message_kit], Ursula.NotEnoughUrsulas
alice_verifying_key=amonia.stamp.as_umbral_pubkey(), ): # Return a more descriptive request error?
encrypted_treasure_map=bupkiss_policy.treasure_map) bob.retrieve_and_decrypt(
[message_kit],
alice_verifying_key=amonia.stamp.as_umbral_pubkey(),
encrypted_treasure_map=bupkiss_policy.treasure_map,
)

View File

@ -10,14 +10,18 @@ from nucypher.characters.unlawful import Vladimir
from nucypher.crypto.utils import verify_eip_191 from nucypher.crypto.utils import verify_eip_191
from nucypher.policy.policies import BlockchainPolicy from nucypher.policy.policies import BlockchainPolicy
from tests.utils.middleware import NodeIsDownMiddleware from tests.utils.middleware import NodeIsDownMiddleware
from tests.utils.ursula import make_decentralized_ursulas from tests.utils.ursula import make_ursulas
@pytest.mark.usefixtures("blockchain_ursulas") @pytest.mark.usefixtures("ursulas")
def test_stakers_bond_to_ursulas(testerchain, test_registry, staking_providers, ursula_decentralized_test_config): def test_stakers_bond_to_ursulas(
ursulas = make_decentralized_ursulas(ursula_config=ursula_decentralized_test_config, testerchain, test_registry, staking_providers, ursula_test_config
staking_provider_addresses=testerchain.stake_providers_accounts, ):
operator_addresses=testerchain.ursulas_accounts) ursulas = make_ursulas(
ursula_config=ursula_test_config,
staking_provider_addresses=testerchain.stake_providers_accounts,
operator_addresses=testerchain.ursulas_accounts,
)
assert len(ursulas) == len(staking_providers) assert len(ursulas) == len(staking_providers)
for ursula in ursulas: for ursula in ursulas:
@ -25,8 +29,8 @@ def test_stakers_bond_to_ursulas(testerchain, test_registry, staking_providers,
assert ursula.verified_operator assert ursula.verified_operator
def test_blockchain_ursula_substantiates_stamp(blockchain_ursulas): def test_ursula_substantiates_stamp(ursulas):
first_ursula = list(blockchain_ursulas)[0] first_ursula = list(ursulas)[0]
signature_as_bytes = first_ursula.operator_signature signature_as_bytes = first_ursula.operator_signature
signature_as_bytes = to_standard_signature_bytes(signature_as_bytes) signature_as_bytes = to_standard_signature_bytes(signature_as_bytes)
# `operator_address` was derived in nucypher_core, check it independently # `operator_address` was derived in nucypher_core, check it independently
@ -35,8 +39,8 @@ def test_blockchain_ursula_substantiates_stamp(blockchain_ursulas):
signature=signature_as_bytes) signature=signature_as_bytes)
def test_blockchain_ursula_verifies_stamp(blockchain_ursulas): def test_blockchain_ursula_verifies_stamp(ursulas):
first_ursula = list(blockchain_ursulas)[0] first_ursula = list(ursulas)[0]
# This Ursula does not yet have a verified stamp # This Ursula does not yet have a verified stamp
first_ursula.verified_stamp = False first_ursula.verified_stamp = False
@ -52,8 +56,8 @@ def remote_vladimir(**kwds):
return remote_vladimir return remote_vladimir
def test_vladimir_cannot_verify_interface_with_ursulas_signing_key(blockchain_ursulas): def test_vladimir_cannot_verify_interface_with_ursulas_signing_key(ursulas):
his_target = list(blockchain_ursulas)[4] his_target = list(ursulas)[4]
# Vladimir has his own ether address; he hopes to publish it along with Ursula's details # Vladimir has his own ether address; he hopes to publish it along with Ursula's details
# so that Alice (or whomever) pays him instead of Ursula, even though Ursula is providing the service. # so that Alice (or whomever) pays him instead of Ursula, even though Ursula is providing the service.
@ -77,12 +81,12 @@ def test_vladimir_cannot_verify_interface_with_ursulas_signing_key(blockchain_ur
vladimir.validate_metadata() vladimir.validate_metadata()
def test_vladimir_uses_his_own_signing_key(blockchain_alice, blockchain_ursulas, test_registry): def test_vladimir_uses_his_own_signing_key(alice, ursulas, test_registry):
""" """
Similar to the attack above, but this time Vladimir makes his own interface signature Similar to the attack above, but this time Vladimir makes his own interface signature
using his own signing key, which he claims is Ursula's. using his own signing key, which he claims is Ursula's.
""" """
his_target = list(blockchain_ursulas)[4] his_target = list(ursulas)[4]
vladimir = remote_vladimir(target_ursula=his_target, vladimir = remote_vladimir(target_ursula=his_target,
sign_metadata=True) sign_metadata=True)
@ -110,8 +114,8 @@ def test_vladimir_uses_his_own_signing_key(blockchain_alice, blockchain_ursulas,
vladimir.validate_metadata(registry=test_registry) vladimir.validate_metadata(registry=test_registry)
def test_vladimir_invalidity_without_stake(testerchain, blockchain_ursulas, blockchain_alice): def test_vladimir_invalidity_without_stake(testerchain, ursulas, alice):
his_target = list(blockchain_ursulas)[4] his_target = list(ursulas)[4]
vladimir = remote_vladimir(target_ursula=his_target, vladimir = remote_vladimir(target_ursula=his_target,
substitute_verifying_key=True, substitute_verifying_key=True,
@ -123,45 +127,51 @@ def test_vladimir_invalidity_without_stake(testerchain, blockchain_ursulas, bloc
# But the actual handshake proves him wrong. # But the actual handshake proves him wrong.
message = "Wallet address swapped out. It appears that someone is trying to defraud this node." message = "Wallet address swapped out. It appears that someone is trying to defraud this node."
with pytest.raises(vladimir.InvalidNode, match=message): with pytest.raises(vladimir.InvalidNode, match=message):
vladimir.verify_node(blockchain_alice.network_middleware.client) vladimir.verify_node(alice.network_middleware.client)
# TODO: Change name of this file, extract this test # TODO: Change name of this file, extract this test
def test_blockchain_ursulas_reencrypt(blockchain_ursulas, blockchain_alice, blockchain_bob, policy_value): def test_blockchain_ursulas_reencrypt(ursulas, alice, bob, policy_value):
label = b'bbo' label = b'bbo'
# TODO: Make sample selection buffer configurable - #1061 # TODO: Make sample selection buffer configurable - #1061
threshold = shares = 10 threshold = shares = 10
expiration = maya.now() + datetime.timedelta(days=35) expiration = maya.now() + datetime.timedelta(days=35)
_policy = blockchain_alice.grant(bob=blockchain_bob, _policy = alice.grant(
label=label, bob=bob,
threshold=threshold, label=label,
shares=shares, threshold=threshold,
expiration=expiration, shares=shares,
value=policy_value) expiration=expiration,
value=policy_value,
)
enrico = Enrico.from_alice(blockchain_alice, label) enrico = Enrico.from_alice(alice, label)
message = b"Oh, this isn't even BO. This is beyond BO. It's BBO." message = b"Oh, this isn't even BO. This is beyond BO. It's BBO."
message_kit = enrico.encrypt_message(message) message_kit = enrico.encrypt_message(message)
blockchain_bob.start_learning_loop(now=True) bob.start_learning_loop(now=True)
plaintexts = blockchain_bob.retrieve_and_decrypt([message_kit], plaintexts = bob.retrieve_and_decrypt(
encrypted_treasure_map=_policy.treasure_map, [message_kit],
alice_verifying_key=blockchain_alice.stamp.as_umbral_pubkey()) encrypted_treasure_map=_policy.treasure_map,
alice_verifying_key=alice.stamp.as_umbral_pubkey(),
)
assert plaintexts == [message] assert plaintexts == [message]
# Let's consider also that a node may be down when granting # Let's consider also that a node may be down when granting
blockchain_alice.network_middleware = NodeIsDownMiddleware() alice.network_middleware = NodeIsDownMiddleware()
blockchain_alice.network_middleware.node_is_down(blockchain_ursulas[0]) alice.network_middleware.node_is_down(ursulas[0])
with pytest.raises(BlockchainPolicy.NotEnoughUrsulas): with pytest.raises(BlockchainPolicy.NotEnoughUrsulas):
_policy = blockchain_alice.grant(bob=blockchain_bob, _policy = alice.grant(
label=b'another-label', bob=bob,
threshold=threshold, label=b"another-label",
shares=shares, threshold=threshold,
expiration=expiration, shares=shares,
value=policy_value) expiration=expiration,
value=policy_value,
)

View File

@ -8,8 +8,8 @@ import pytest
@pytest.fixture(scope='module') @pytest.fixture(scope='module')
def ursula(blockchain_ursulas): def ursula(ursulas):
ursula = blockchain_ursulas[3] ursula = ursulas[3]
return ursula return ursula
@ -30,7 +30,7 @@ def test_ursula_html_renders(ursula, client):
@pytest.mark.parametrize('omit_known_nodes', [False, True]) @pytest.mark.parametrize('omit_known_nodes', [False, True])
def test_decentralized_json_status_endpoint(ursula, client, omit_known_nodes): def test_json_status_endpoint(ursula, client, omit_known_nodes):
omit_known_nodes_str = 'true' if omit_known_nodes else 'false' omit_known_nodes_str = 'true' if omit_known_nodes else 'false'
response = client.get(f'/status/?json=true&omit_known_nodes={omit_known_nodes_str}') response = client.get(f'/status/?json=true&omit_known_nodes={omit_known_nodes_str}')
assert response.status_code == 200 assert response.status_code == 200

View File

@ -37,19 +37,15 @@ def test_missing_configuration_file(_default_filepath_mock, click_runner):
@pt.inlineCallbacks @pt.inlineCallbacks
def test_ursula_run_with_prometheus_but_no_metrics_port(click_runner): def test_ursula_run_with_prometheus_but_no_metrics_port(click_runner):
args = ( args = ('ursula', 'run', # Stat Ursula Command
"ursula", '--debug', # Display log output; Do not attach console
"run", # Stat Ursula Command '--dev', # Run in development mode (local ephemeral node)
"--debug", # Display log output; Do not attach console '--dry-run', # Disable twisted reactor in subprocess
"--dev", # Run in development mode (local ephemeral node) '--lonely', # Do not load seednodes
"--dry-run", # Disable twisted reactor in subprocess '--prometheus', # Specify collection of prometheus metrics
"--lonely", # Do not load seednodes '--eth-provider', TEST_ETH_PROVIDER_URI,
"--prometheus", # Specify collection of prometheus metrics '--payment-provider', TEST_POLYGON_PROVIDER_URI
"--eth-provider", )
TEST_ETH_PROVIDER_URI,
"--payment-provider",
TEST_POLYGON_PROVIDER_URI,
)
result = yield threads.deferToThread(click_runner.invoke, result = yield threads.deferToThread(click_runner.invoke,
nucypher_cli, args, nucypher_cli, args,
@ -61,33 +57,20 @@ def test_ursula_run_with_prometheus_but_no_metrics_port(click_runner):
@pt.inlineCallbacks @pt.inlineCallbacks
def test_run_lone_default_development_ursula( def test_run_lone_default_development_ursula(click_runner, test_registry_source_manager, testerchain, agency, mock_funding_and_bonding):
click_runner,
test_registry_source_manager,
testerchain,
agency,
mock_funding_and_bonding,
):
deploy_port = select_test_port() deploy_port = select_test_port()
args = ( args = ('ursula', 'run', # Stat Ursula Command
"ursula", '--debug', # Display log output; Do not attach console
"run", # Stat Ursula Command '--rest-port', deploy_port, # Network Port
"--debug", # Display log output; Do not attach console '--dev', # Run in development mode (ephemeral node)
"--rest-port", '--dry-run', # Disable twisted reactor in subprocess
deploy_port, # Network Port '--lonely', # Do not load seednodes,
"--dev", # Run in development mode (ephemeral node) '--operator-address', testerchain.etherbase_account,
"--dry-run", # Disable twisted reactor in subprocess '--eth-provider', TEST_ETH_PROVIDER_URI,
"--lonely", # Do not load seednodes, '--payment-provider', TEST_ETH_PROVIDER_URI,
"--operator-address", '--payment-network', TEMPORARY_DOMAIN,
testerchain.etherbase_account, )
"--eth-provider",
TEST_ETH_PROVIDER_URI,
"--payment-provider",
TEST_ETH_PROVIDER_URI,
"--payment-network",
TEMPORARY_DOMAIN,
)
result = yield threads.deferToThread(click_runner.invoke, result = yield threads.deferToThread(click_runner.invoke,
nucypher_cli, args, nucypher_cli, args,
@ -105,36 +88,28 @@ def test_run_lone_default_development_ursula(
@pt.inlineCallbacks @pt.inlineCallbacks
def test_ursula_learns_via_cli( def test_ursula_learns_via_cli(
click_runner, blockchain_ursulas, testerchain, agency, mock_funding_and_bonding click_runner, ursulas, testerchain, agency, mock_funding_and_bonding
): ):
# Establish a running Teacher Ursula # Establish a running Teacher Ursula
teacher = list(blockchain_ursulas)[0] teacher = list(ursulas)[0]
teacher_uri = teacher.seed_node_metadata(as_teacher_uri=True) teacher_uri = teacher.seed_node_metadata(as_teacher_uri=True)
deploy_port = select_test_port() deploy_port = select_test_port()
def run_ursula(): def run_ursula():
i = start_pytest_ursula_services(ursula=teacher) i = start_pytest_ursula_services(ursula=teacher)
args = ( args = ('ursula', 'run',
"ursula", '--debug', # Display log output; Do not attach console
"run", '--rest-port', deploy_port, # Network Port
"--debug", # Display log output; Do not attach console '--teacher', teacher_uri,
"--rest-port", '--dev', # Run in development mode (ephemeral node)
deploy_port, # Network Port '--dry-run', # Disable twisted reactor
"--teacher", '--operator-address', testerchain.etherbase_account,
teacher_uri, '--eth-provider', TEST_ETH_PROVIDER_URI,
"--dev", # Run in development mode (ephemeral node) '--payment-provider', TEST_ETH_PROVIDER_URI,
"--dry-run", # Disable twisted reactor '--payment-network', TEMPORARY_DOMAIN
"--operator-address", )
testerchain.etherbase_account,
"--eth-provider",
TEST_ETH_PROVIDER_URI,
"--payment-provider",
TEST_ETH_PROVIDER_URI,
"--payment-network",
TEMPORARY_DOMAIN,
)
return threads.deferToThread(click_runner.invoke, return threads.deferToThread(click_runner.invoke,
nucypher_cli, args, nucypher_cli, args,
@ -159,11 +134,9 @@ def test_ursula_learns_via_cli(
@pt.inlineCallbacks @pt.inlineCallbacks
def test_persistent_node_storage_integration(click_runner, def test_persistent_node_storage_integration(
custom_filepath, click_runner, custom_filepath, testerchain, ursulas, agency_local_registry
testerchain, ):
blockchain_ursulas,
agency_local_registry):
alice, ursula, another_ursula, staking_provider, *all_yall = testerchain.unassigned_accounts alice, ursula, another_ursula, staking_provider, *all_yall = testerchain.unassigned_accounts
filename = UrsulaConfiguration.generate_filename() filename = UrsulaConfiguration.generate_filename()
@ -184,7 +157,7 @@ def test_persistent_node_storage_integration(click_runner,
result = click_runner.invoke(nucypher_cli, init_args, catch_exceptions=False, env=envvars) result = click_runner.invoke(nucypher_cli, init_args, catch_exceptions=False, env=envvars)
assert result.exit_code == 0 assert result.exit_code == 0
teacher = blockchain_ursulas[-1] teacher = ursulas[-1]
teacher_uri = teacher.rest_information()[0].uri teacher_uri = teacher.rest_information()[0].uri
start_pytest_ursula_services(ursula=teacher) start_pytest_ursula_services(ursula=teacher)

View File

@ -15,123 +15,73 @@ from tests.constants import (
@pytest.mark.skip("Hangs for unknown reason. Refuses to exit.") @pytest.mark.skip("Hangs for unknown reason. Refuses to exit.")
def test_ursula_startup_ip_checkup(click_runner, mocker): def test_ursula_startup_ip_checkup(click_runner, mocker):
target = "nucypher.cli.actions.configure.determine_external_ip_address" target = 'nucypher.cli.actions.configure.determine_external_ip_address'
# Patch the get_external_ip call # Patch the get_external_ip call
mocker.patch(target, return_value=MOCK_IP_ADDRESS) mocker.patch(target, return_value=MOCK_IP_ADDRESS)
mocker.patch.object(UrsulaConfiguration, "to_configuration_file", return_value=None) mocker.patch.object(UrsulaConfiguration, 'to_configuration_file', return_value=None)
args = ( args = ('ursula', 'init', '--network', TEMPORARY_DOMAIN, '--eth-provider', TEST_ETH_PROVIDER_URI, '--payment-provider', TEST_POLYGON_PROVIDER_URI, '--force')
"ursula",
"init",
"--network",
TEMPORARY_DOMAIN,
"--eth-provider",
TEST_ETH_PROVIDER_URI,
"--payment-provider",
TEST_POLYGON_PROVIDER_URI,
"--force",
)
user_input = FAKE_PASSWORD_CONFIRMED user_input = FAKE_PASSWORD_CONFIRMED
result = click_runner.invoke( result = click_runner.invoke(nucypher_cli, args, catch_exceptions=False, input=user_input)
nucypher_cli, args, catch_exceptions=False, input=user_input
)
assert result.exit_code == 0 assert result.exit_code == 0
assert MOCK_IP_ADDRESS in result.output assert MOCK_IP_ADDRESS in result.output
args = ( args = ('ursula', 'init', '--network', TEMPORARY_DOMAIN, '--force', '--eth-provider', TEST_ETH_PROVIDER_URI, '--payment-provider', TEST_POLYGON_PROVIDER_URI)
"ursula", result = click_runner.invoke(nucypher_cli, args, catch_exceptions=False, input=FAKE_PASSWORD_CONFIRMED)
"init",
"--network",
TEMPORARY_DOMAIN,
"--force",
"--eth-provider",
TEST_ETH_PROVIDER_URI,
"--payment-provider",
TEST_POLYGON_PROVIDER_URI,
)
result = click_runner.invoke(
nucypher_cli, args, catch_exceptions=False, input=FAKE_PASSWORD_CONFIRMED
)
assert result.exit_code == 0 assert result.exit_code == 0
# Patch get_external_ip call to error output # Patch get_external_ip call to error output
mocker.patch(target, side_effect=UnknownIPAddress) mocker.patch(target, side_effect=UnknownIPAddress)
args = ( args = ('ursula', 'init', '--network', TEMPORARY_DOMAIN, '--force', '--eth-provider', TEST_ETH_PROVIDER_URI, '--payment-provider', TEST_POLYGON_PROVIDER_URI)
"ursula", result = click_runner.invoke(nucypher_cli, args, catch_exceptions=True, input=FAKE_PASSWORD_CONFIRMED)
"init",
"--network",
TEMPORARY_DOMAIN,
"--force",
"--eth-provider",
TEST_ETH_PROVIDER_URI,
"--payment-provider",
TEST_POLYGON_PROVIDER_URI,
)
result = click_runner.invoke(
nucypher_cli, args, catch_exceptions=True, input=FAKE_PASSWORD_CONFIRMED
)
assert result.exit_code == 1, result.output assert result.exit_code == 1, result.output
assert isinstance(result.exception, UnknownIPAddress) assert isinstance(result.exception, UnknownIPAddress)
@pytest.mark.skip("Depends on previous test") @pytest.mark.skip("Depends on previous test")
def test_ursula_run_ip_checkup( def test_ursula_run_ip_checkup(
testerchain, custom_filepath, click_runner, mocker, blockchain_ursulas, monkeypatch testerchain, custom_filepath, click_runner, mocker, ursulas, monkeypatch
): ):
# Mock IP determination # Mock IP determination
target = "nucypher.cli.actions.configure.determine_external_ip_address" target = 'nucypher.cli.actions.configure.determine_external_ip_address'
mocker.patch(target, return_value=MOCK_IP_ADDRESS) mocker.patch(target, return_value=MOCK_IP_ADDRESS)
# Mock Teacher Resolution # Mock Teacher Resolution
from nucypher.characters.lawful import Ursula from nucypher.characters.lawful import Ursula
teacher = blockchain_ursulas[0] teacher = ursulas[0]
mocker.patch.object(Ursula, "from_teacher_uri", return_value=teacher) mocker.patch.object(Ursula, 'from_teacher_uri', return_value=teacher)
# Mock worker qualification # Mock worker qualification
staking_provider = blockchain_ursulas[1] staking_provider = ursulas[1]
def set_staking_provider_address(operator, *args, **kwargs): def set_staking_provider_address(operator, *args, **kwargs):
operator.checksum_address = staking_provider.checksum_address operator.checksum_address = staking_provider.checksum_address
return True return True
monkeypatch.setattr(Operator, 'block_until_ready', set_staking_provider_address)
monkeypatch.setattr(Operator, "block_until_ready", set_staking_provider_address)
# Setup # Setup
teacher = blockchain_ursulas[2] teacher = ursulas[2]
filename = UrsulaConfiguration.generate_filename() filename = UrsulaConfiguration.generate_filename()
another_ursula_configuration_file_location = custom_filepath / filename another_ursula_configuration_file_location = custom_filepath / filename
# manual teacher # manual teacher
run_args = ( run_args = ('ursula', 'run',
"ursula", '--dry-run',
"run", '--debug',
"--dry-run", '--config-file', str(another_ursula_configuration_file_location.absolute()),
"--debug", '--teacher', teacher.rest_url())
"--config-file", result = click_runner.invoke(nucypher_cli, run_args, catch_exceptions=False, input=FAKE_PASSWORD_CONFIRMED)
str(another_ursula_configuration_file_location.absolute()),
"--teacher",
teacher.rest_url(),
)
result = click_runner.invoke(
nucypher_cli, run_args, catch_exceptions=False, input=FAKE_PASSWORD_CONFIRMED
)
assert result.exit_code == 0, result.output assert result.exit_code == 0, result.output
# default teacher # default teacher
run_args = ( run_args = ('ursula', 'run',
"ursula", '--dry-run',
"run", '--debug',
"--dry-run", '--config-file', str(another_ursula_configuration_file_location.absolute()))
"--debug", result = click_runner.invoke(nucypher_cli, run_args, catch_exceptions=False, input=FAKE_PASSWORD_CONFIRMED)
"--config-file",
str(another_ursula_configuration_file_location.absolute()),
)
result = click_runner.invoke(
nucypher_cli, run_args, catch_exceptions=False, input=FAKE_PASSWORD_CONFIRMED
)
assert result.exit_code == 0, result.output assert result.exit_code == 0, result.output
blockchain_ursulas.clear() ursulas.clear()

View File

@ -10,13 +10,12 @@ from tests.utils.middleware import MockRestMiddleware
from tests.utils.ursula import make_ursula_for_staking_provider from tests.utils.ursula import make_ursula_for_staking_provider
# @pytest.mark.skip() def test_ursula_stamp_verification_tolerance(ursulas, mocker):
def test_blockchain_ursula_stamp_verification_tolerance(blockchain_ursulas, mocker):
# #
# Setup # Setup
# #
lonely_blockchain_learner, blockchain_teacher, unsigned, *the_others = list(blockchain_ursulas) lonely_learner, teacher, unsigned, *the_others = list(ursulas)
warnings = [] warnings = []
@ -30,12 +29,12 @@ def test_blockchain_ursula_stamp_verification_tolerance(blockchain_ursulas, mock
unsigned._metadata = None unsigned._metadata = None
# Wipe known nodes! # Wipe known nodes!
lonely_blockchain_learner._Learner__known_nodes = FleetSensor(domain=TEMPORARY_DOMAIN) lonely_learner._Learner__known_nodes = FleetSensor(domain=TEMPORARY_DOMAIN)
lonely_blockchain_learner._current_teacher_node = blockchain_teacher lonely_learner._current_teacher_node = teacher
lonely_blockchain_learner.remember_node(blockchain_teacher) lonely_learner.remember_node(teacher)
globalLogPublisher.addObserver(warning_trapper) globalLogPublisher.addObserver(warning_trapper)
lonely_blockchain_learner.learn_from_teacher_node(eager=True) lonely_learner.learn_from_teacher_node(eager=True)
globalLogPublisher.removeObserver(warning_trapper) globalLogPublisher.removeObserver(warning_trapper)
# We received one warning during learning, and it was about this very matter. # We received one warning during learning, and it was about this very matter.
@ -45,47 +44,52 @@ def test_blockchain_ursula_stamp_verification_tolerance(blockchain_ursulas, mock
assert "Verification Failed" in warning # TODO: Cleanup logging templates assert "Verification Failed" in warning # TODO: Cleanup logging templates
# TODO: Buckets! #567 # TODO: Buckets! #567
# assert unsigned not in lonely_blockchain_learner.known_nodes # assert unsigned not in lonely_learner.known_nodes
# minus 2: self and the unsigned ursula. # minus 2: self and the unsigned ursula.
# assert len(lonely_blockchain_learner.known_nodes) == len(blockchain_ursulas) - 2 # assert len(lonely_learner.known_nodes) == len(ursulas) - 2
assert blockchain_teacher in lonely_blockchain_learner.known_nodes assert teacher in lonely_learner.known_nodes
# Learn about a node with a badly signed payload # Learn about a node with a badly signed payload
def bad_bytestring_of_known_nodes(): def bad_bytestring_of_known_nodes():
# Signing with the learner's signer instead of the teacher's signer # Signing with the learner's signer instead of the teacher's signer
response_payload = MetadataResponsePayload(timestamp_epoch=blockchain_teacher.known_nodes.timestamp.epoch, response_payload = MetadataResponsePayload(
announce_nodes=[]) timestamp_epoch=teacher.known_nodes.timestamp.epoch, announce_nodes=[]
response = MetadataResponse(signer=lonely_blockchain_learner.stamp.as_umbral_signer(), )
payload=response_payload) response = MetadataResponse(
signer=lonely_learner.stamp.as_umbral_signer(), payload=response_payload
)
return bytes(response) return bytes(response)
mocker.patch.object(blockchain_teacher, 'bytestring_of_known_nodes', bad_bytestring_of_known_nodes) mocker.patch.object(
teacher, "bytestring_of_known_nodes", bad_bytestring_of_known_nodes
)
globalLogPublisher.addObserver(warning_trapper) globalLogPublisher.addObserver(warning_trapper)
lonely_blockchain_learner.learn_from_teacher_node(eager=True) lonely_learner.learn_from_teacher_node(eager=True)
globalLogPublisher.removeObserver(warning_trapper) globalLogPublisher.removeObserver(warning_trapper)
assert len(warnings) == 2 assert len(warnings) == 2
warning = warnings[1]['log_format'] warning = warnings[1]['log_format']
assert str(blockchain_teacher) in warning assert str(teacher) in warning
assert "Failed to verify MetadataResponse from Teacher" in warning # TODO: Cleanup logging templates assert "Failed to verify MetadataResponse from Teacher" in warning # TODO: Cleanup logging templates
@pytest.mark.skip("See Issue #1075") # TODO: Issue #1075 @pytest.mark.skip("See Issue #1075") # TODO: Issue #1075
def test_invalid_operators_tolerance(testerchain, def test_invalid_operators_tolerance(
test_registry, testerchain,
blockchain_ursulas, test_registry,
agency, ursulas,
idle_staker, agency,
application_economics, idle_staker,
ursula_decentralized_test_config application_economics,
): ursula_test_config,
):
# #
# Setup # Setup
# #
lonely_blockchain_learner, blockchain_teacher, unsigned, *the_others = list(blockchain_ursulas) lonely_blockchain_learner, blockchain_teacher, unsigned, *the_others = list(ursulas)
_, staking_agent, _ = agency _, staking_agent, _ = agency
warnings = [] warnings = []
@ -109,11 +113,13 @@ def test_invalid_operators_tolerance(testerchain,
idle_staker.stake_tracker.refresh() idle_staker.stake_tracker.refresh()
# We create an active worker node for this staker # We create an active worker node for this staker
worker = make_ursula_for_staking_provider(staking_provider=idle_staker, worker = make_ursula_for_staking_provider(
operator_address=testerchain.unassigned_accounts[-1], staking_provider=idle_staker,
ursula_config=ursula_decentralized_test_config, operator_address=testerchain.unassigned_accounts[-1],
blockchain=testerchain, ursula_config=ursula_test_config,
ursulas_to_learn_about=None) blockchain=testerchain,
ursulas_to_learn_about=None,
)
# Since we made a commitment, we need to advance one period # Since we made a commitment, we need to advance one period
testerchain.time_travel(periods=1) testerchain.time_travel(periods=1)

View File

@ -13,10 +13,10 @@ from tests.utils.ursula import start_pytest_ursula_services
@pytest.mark.skip('See #2024 - skipped tests') @pytest.mark.skip('See #2024 - skipped tests')
@pt.inlineCallbacks @pt.inlineCallbacks
def test_availability_tracker_success(blockchain_ursulas): def test_availability_tracker_success(ursulas):
# Start up self-services # Start up self-services
ursula = blockchain_ursulas[6] ursula = ursulas[6]
start_pytest_ursula_services(ursula=ursula) start_pytest_ursula_services(ursula=ursula)
ursula._availability_tracker = AvailabilityTracker(ursula=ursula) ursula._availability_tracker = AvailabilityTracker(ursula=ursula)
@ -80,10 +80,10 @@ def test_availability_tracker_success(blockchain_ursulas):
@pytest.mark.skip('See #2024 - skipped tests') @pytest.mark.skip('See #2024 - skipped tests')
@pt.inlineCallbacks @pt.inlineCallbacks
def test_availability_tracker_integration(blockchain_ursulas, monkeypatch): def test_availability_tracker_integration(ursulas, monkeypatch):
# Start up self-services # Start up self-services
ursula = blockchain_ursulas[8] ursula = ursulas[8]
start_pytest_ursula_services(ursula=ursula) start_pytest_ursula_services(ursula=ursula)
ursula._availability_tracker = AvailabilityTracker(ursula=ursula) ursula._availability_tracker = AvailabilityTracker(ursula=ursula)

View File

@ -13,7 +13,7 @@ from nucypher.config.constants import TEMPORARY_DOMAIN
from tests.utils.middleware import MockRestMiddleware from tests.utils.middleware import MockRestMiddleware
def test_all_blockchain_ursulas_know_about_all_other_ursulas(blockchain_ursulas, agency, test_registry): def test_all_ursulas_know_about_all_other_ursulas(ursulas, agency, test_registry):
""" """
Once launched, all Ursulas know about - and can help locate - all other Ursulas in the network. Once launched, all Ursulas know about - and can help locate - all other Ursulas in the network.
""" """
@ -21,7 +21,7 @@ def test_all_blockchain_ursulas_know_about_all_other_ursulas(blockchain_ursulas,
for record in application_agent.get_active_staking_providers(0, 10)[1]: for record in application_agent.get_active_staking_providers(0, 10)[1]:
address = to_checksum_address(record[0]) #TODO: something better address = to_checksum_address(record[0]) #TODO: something better
for propagating_ursula in blockchain_ursulas[:1]: # Last Ursula is not staking for propagating_ursula in ursulas[:1]: # Last Ursula is not staking
if address == propagating_ursula.checksum_address: if address == propagating_ursula.checksum_address:
continue continue
else: else:
@ -29,19 +29,19 @@ def test_all_blockchain_ursulas_know_about_all_other_ursulas(blockchain_ursulas,
format(propagating_ursula, Nickname.from_seed(address)) format(propagating_ursula, Nickname.from_seed(address))
def test_blockchain_alice_finds_ursula_via_rest(blockchain_alice, blockchain_ursulas): def test_blockchain_alice_finds_ursula_via_rest(alice, ursulas):
# Imagine alice knows of nobody. # Imagine alice knows of nobody.
blockchain_alice._Learner__known_nodes = FleetSensor(domain=TEMPORARY_DOMAIN) alice._Learner__known_nodes = FleetSensor(domain=TEMPORARY_DOMAIN)
blockchain_alice.remember_node(blockchain_ursulas[0]) alice.remember_node(ursulas[0])
blockchain_alice.learn_from_teacher_node() alice.learn_from_teacher_node()
assert len(blockchain_alice.known_nodes) == len(blockchain_ursulas) assert len(alice.known_nodes) == len(ursulas)
for ursula in blockchain_ursulas: for ursula in ursulas:
assert ursula in blockchain_alice.known_nodes assert ursula in alice.known_nodes
def test_vladimir_illegal_interface_key_does_not_propagate(blockchain_ursulas): def test_vladimir_illegal_interface_key_does_not_propagate(ursulas):
""" """
Although Ursulas propagate each other's interface information, as demonstrated above, Although Ursulas propagate each other's interface information, as demonstrated above,
they do not propagate interface information for Vladimir. they do not propagate interface information for Vladimir.
@ -59,7 +59,7 @@ def test_vladimir_illegal_interface_key_does_not_propagate(blockchain_ursulas):
warnings.append(event) warnings.append(event)
ursulas = list(blockchain_ursulas) ursulas = list(ursulas)
ursula_whom_vladimir_will_imitate, other_ursula = ursulas[0], ursulas[1] ursula_whom_vladimir_will_imitate, other_ursula = ursulas[0], ursulas[1]
# Vladimir sees Ursula on the network and tries to use her public information. # Vladimir sees Ursula on the network and tries to use her public information.
@ -97,11 +97,11 @@ def test_vladimir_illegal_interface_key_does_not_propagate(blockchain_ursulas):
# assert vladimir not in other_ursula.known_nodes # assert vladimir not in other_ursula.known_nodes
def test_alice_refuses_to_select_node_unless_ursula_is_valid(blockchain_alice, def test_alice_refuses_to_select_node_unless_ursula_is_valid(
idle_blockchain_policy, alice, idle_policy, ursulas
blockchain_ursulas): ):
target = list(blockchain_ursulas)[2] target = list(ursulas)[2]
# First, let's imagine that Alice has sampled a Vladimir while making this policy. # First, let's imagine that Alice has sampled a Vladimir while making this policy.
vladimir = Vladimir.from_target_ursula(target, vladimir = Vladimir.from_target_ursula(target,
substitute_verifying_key=True, substitute_verifying_key=True,
@ -112,9 +112,11 @@ def test_alice_refuses_to_select_node_unless_ursula_is_valid(blockchain_alice,
# Ideally, a fishy node will be present in `known_nodes`, # Ideally, a fishy node will be present in `known_nodes`,
# This tests the case when it became fishy after discovering it # This tests the case when it became fishy after discovering it
# but before being selected for a policy. # but before being selected for a policy.
blockchain_alice.known_nodes.record_node(vladimir) alice.known_nodes.record_node(vladimir)
blockchain_alice.known_nodes.record_fleet_state() alice.known_nodes.record_fleet_state()
with pytest.raises(vladimir.InvalidNode): with pytest.raises(vladimir.InvalidNode):
idle_blockchain_policy._ping_node(address=vladimir.checksum_address, idle_policy._ping_node(
network_middleware=blockchain_alice.network_middleware) address=vladimir.checksum_address,
network_middleware=alice.network_middleware,
)

View File

@ -7,17 +7,17 @@ import requests
from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import serialization
from twisted.internet import threads from twisted.internet import threads
from tests.utils.ursula import make_decentralized_ursulas from tests.utils.ursula import make_ursulas
@pytest_twisted.inlineCallbacks @pytest_twisted.inlineCallbacks
def test_ursula_serves_statics(ursula_decentralized_test_config, testerchain, agency): def test_ursula_serves_statics(ursula_test_config, testerchain, agency):
with tempfile.TemporaryDirectory() as STATICS_DIR: with tempfile.TemporaryDirectory() as STATICS_DIR:
os.environ['NUCYPHER_STATIC_FILES_ROOT'] = str(STATICS_DIR) os.environ['NUCYPHER_STATIC_FILES_ROOT'] = str(STATICS_DIR)
node = make_decentralized_ursulas( node = make_ursulas(
ursula_config=ursula_decentralized_test_config, ursula_config=ursula_test_config,
quantity=1, quantity=1,
staking_provider_addresses=testerchain.stake_providers_accounts, staking_provider_addresses=testerchain.stake_providers_accounts,
operator_addresses=testerchain.ursulas_accounts, operator_addresses=testerchain.ursulas_accounts,

View File

@ -28,11 +28,12 @@ except ImportError:
PROMETHEUS_INSTALLED = False PROMETHEUS_INSTALLED = False
@pytest.mark.skipif(condition=(not PROMETHEUS_INSTALLED), reason="prometheus_client is required for test") @pytest.mark.skipif(
def test_ursula_info_metrics_collector(test_registry, condition=(not PROMETHEUS_INSTALLED),
blockchain_ursulas, reason="prometheus_client is required for test",
agency): )
ursula = random.choice(blockchain_ursulas) def test_ursula_info_metrics_collector(test_registry, ursulas, agency):
ursula = random.choice(ursulas)
collector = UrsulaInfoMetricsCollector(ursula=ursula) collector = UrsulaInfoMetricsCollector(ursula=ursula)
collector_registry = CollectorRegistry() collector_registry = CollectorRegistry()
@ -119,8 +120,8 @@ def test_staking_provider_metrics_collector(test_registry, staking_providers):
@pytest.mark.skipif(condition=(not PROMETHEUS_INSTALLED), reason="prometheus_client is required for test") @pytest.mark.skipif(condition=(not PROMETHEUS_INSTALLED), reason="prometheus_client is required for test")
def test_operator_metrics_collector(test_registry, blockchain_ursulas): def test_operator_metrics_collector(test_registry, ursulas):
ursula = random.choice(blockchain_ursulas) ursula = random.choice(ursulas)
collector = OperatorMetricsCollector( collector = OperatorMetricsCollector(
domain=ursula.domain, domain=ursula.domain,
operator_address=ursula.operator_address, operator_address=ursula.operator_address,
@ -137,8 +138,8 @@ def test_operator_metrics_collector(test_registry, blockchain_ursulas):
@pytest.mark.skipif(condition=(not PROMETHEUS_INSTALLED), reason="prometheus_client is required for test") @pytest.mark.skipif(condition=(not PROMETHEUS_INSTALLED), reason="prometheus_client is required for test")
def test_all_metrics_collectors_sanity_collect(blockchain_ursulas): def test_all_metrics_collectors_sanity_collect(ursulas):
ursula = random.choice(blockchain_ursulas) ursula = random.choice(ursulas)
collector_registry = CollectorRegistry() collector_registry = CollectorRegistry()
prefix = 'test_all_metrics_collectors' prefix = 'test_all_metrics_collectors'

View File

@ -46,7 +46,7 @@ from nucypher.config.characters import (
) )
from nucypher.config.constants import TEMPORARY_DOMAIN from nucypher.config.constants import TEMPORARY_DOMAIN
from nucypher.crypto.keystore import Keystore from nucypher.crypto.keystore import Keystore
from nucypher.crypto.powers import TransactingPower from nucypher.crypto.powers import CryptoPower, TransactingPower
from nucypher.network.nodes import TEACHER_NODES from nucypher.network.nodes import TEACHER_NODES
from nucypher.policy.conditions.context import USER_ADDRESS_CONTEXT from nucypher.policy.conditions.context import USER_ADDRESS_CONTEXT
from nucypher.policy.conditions.evm import ContractCondition, RPCCondition from nucypher.policy.conditions.evm import ContractCondition, RPCCondition
@ -93,11 +93,7 @@ from tests.utils.middleware import (
MockRestMiddlewareForLargeFleetTests, MockRestMiddlewareForLargeFleetTests,
) )
from tests.utils.policy import generate_random_label from tests.utils.policy import generate_random_label
from tests.utils.ursula import ( from tests.utils.ursula import MOCK_KNOWN_URSULAS_CACHE, make_ursulas, select_test_port
MOCK_KNOWN_URSULAS_CACHE,
make_decentralized_ursulas,
select_test_port,
)
test_logger = Logger("test-logger") test_logger = Logger("test-logger")
@ -138,7 +134,7 @@ def certificates_tempdir():
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def ursula_decentralized_test_config(test_registry, temp_dir_path): def ursula_test_config(test_registry, temp_dir_path):
config = make_ursula_test_configuration( config = make_ursula_test_configuration(
eth_provider_uri=TEST_ETH_PROVIDER_URI, eth_provider_uri=TEST_ETH_PROVIDER_URI,
payment_provider=TEST_ETH_PROVIDER_URI, payment_provider=TEST_ETH_PROVIDER_URI,
@ -152,11 +148,11 @@ def ursula_decentralized_test_config(test_registry, temp_dir_path):
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def alice_blockchain_test_config(blockchain_ursulas, testerchain, test_registry): def alice_test_config(ursulas, testerchain, test_registry):
config = make_alice_test_configuration( config = make_alice_test_configuration(
eth_provider_uri=TEST_ETH_PROVIDER_URI, eth_provider_uri=TEST_ETH_PROVIDER_URI,
payment_provider=TEST_ETH_PROVIDER_URI, payment_provider=TEST_ETH_PROVIDER_URI,
known_nodes=blockchain_ursulas, known_nodes=ursulas,
checksum_address=testerchain.alice_account, checksum_address=testerchain.alice_account,
test_registry=test_registry, test_registry=test_registry,
) )
@ -165,12 +161,10 @@ def alice_blockchain_test_config(blockchain_ursulas, testerchain, test_registry)
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def bob_blockchain_test_config(testerchain, test_registry): def bob_test_config(testerchain, test_registry):
config = make_bob_test_configuration( config = make_bob_test_configuration(eth_provider_uri=TEST_ETH_PROVIDER_URI,
eth_provider_uri=TEST_ETH_PROVIDER_URI, test_registry=test_registry,
test_registry=test_registry, checksum_address=testerchain.bob_account)
checksum_address=testerchain.bob_account,
)
yield config yield config
config.cleanup() config.cleanup()
@ -181,70 +175,78 @@ def bob_blockchain_test_config(testerchain, test_registry):
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def idle_blockchain_policy(testerchain, blockchain_alice, blockchain_bob, application_economics): def idle_policy(testerchain, alice, bob, application_economics):
"""Creates a Policy, in a manner typical of how Alice might do it, with a unique label""" """Creates a Policy, in a manner typical of how Alice might do it, with a unique label"""
random_label = generate_random_label() random_label = generate_random_label()
expiration = maya.now() + timedelta(days=1) expiration = maya.now() + timedelta(days=1)
threshold, shares = 2, 3 threshold, shares = 2, 3
price = blockchain_alice.payment_method.quote(expiration=expiration.epoch, shares=shares).value # TODO: use default quote option price = alice.payment_method.quote(
policy = blockchain_alice.create_policy(blockchain_bob, expiration=expiration.epoch, shares=shares
label=random_label, ).value # TODO: use default quote option
value=price, policy = alice.create_policy(
threshold=threshold, bob,
shares=shares, label=random_label,
expiration=expiration) value=price,
threshold=threshold,
shares=shares,
expiration=expiration,
)
return policy return policy
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def enacted_blockchain_policy(idle_blockchain_policy, blockchain_ursulas): def enacted_policy(idle_policy, ursulas):
# Alice has a policy in mind and knows of enough qualified Ursulas; she crafts an offer for them. # Alice has a policy in mind and knows of enough qualified Ursulas; she crafts an offer for them.
# value and expiration were set when creating idle_blockchain_policy already # value and expiration were set when creating idle_policy already
# cannot set them again # cannot set them again
# deposit = NON_PAYMENT(b"0000000") # deposit = NON_PAYMENT(b"0000000")
# contract_end_datetime = maya.now() + datetime.timedelta(days=5) # contract_end_datetime = maya.now() + datetime.timedelta(days=5)
network_middleware = MockRestMiddleware() network_middleware = MockRestMiddleware()
# REST call happens here, as does population of TreasureMap. # REST call happens here, as does population of TreasureMap.
enacted_policy = idle_blockchain_policy.enact(network_middleware=network_middleware, enacted_policy = idle_policy.enact(
ursulas=list(blockchain_ursulas)) network_middleware=network_middleware, ursulas=list(ursulas)
)
return enacted_policy return enacted_policy
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def blockchain_treasure_map(enacted_blockchain_policy, blockchain_bob): def treasure_map(enacted_policy, bob):
""" """
The unencrypted treasure map corresponding to the one in `enacted_blockchain_policy` The unencrypted treasure map corresponding to the one in `enacted_policy`
""" """
yield blockchain_bob._decrypt_treasure_map(enacted_blockchain_policy.treasure_map, yield bob._decrypt_treasure_map(
enacted_blockchain_policy.publisher_verifying_key) enacted_policy.treasure_map, enacted_policy.publisher_verifying_key
)
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
def random_blockchain_policy(testerchain, blockchain_alice, blockchain_bob, application_economics): def random_policy(testerchain, alice, bob, application_economics):
random_label = generate_random_label() random_label = generate_random_label()
seconds = 60 * 60 * 24 # TODO This needs to be better thought out...? seconds = 60 * 60 * 24 # TODO This needs to be better thought out...?
now = testerchain.w3.eth.get_block('latest').timestamp now = testerchain.w3.eth.get_block('latest').timestamp
expiration = maya.MayaDT(now).add(seconds=seconds) expiration = maya.MayaDT(now).add(seconds=seconds)
shares = 3 shares = 3
threshold = 2 threshold = 2
policy = blockchain_alice.create_policy(blockchain_bob, policy = alice.create_policy(
label=random_label, bob,
threshold=threshold, label=random_label,
shares=shares, threshold=threshold,
value=shares * seconds * 100, # calculation probably needs to incorporate actual cost per second shares=shares,
expiration=expiration) value=shares
* seconds
* 100, # calculation probably needs to incorporate actual cost per second
expiration=expiration,
)
return policy return policy
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def capsule_side_channel(enacted_blockchain_policy): def capsule_side_channel(enacted_policy):
class _CapsuleSideChannel: class _CapsuleSideChannel:
def __init__(self): def __init__(self):
self.enrico = Enrico( self.enrico = Enrico(policy_encrypting_key=enacted_policy.public_key)
policy_encrypting_key=enacted_blockchain_policy.public_key
)
self.messages = [] self.messages = []
self.plaintexts = [] self.plaintexts = []
self.plaintext_passthrough = False self.plaintext_passthrough = False
@ -258,7 +260,7 @@ def capsule_side_channel(enacted_blockchain_policy):
return message_kit return message_kit
def reset(self, plaintext_passthrough=False): def reset(self, plaintext_passthrough=False):
self.enrico = Enrico(policy_encrypting_key=enacted_blockchain_policy.public_key) self.enrico = Enrico(policy_encrypting_key=enacted_policy.public_key)
self.messages.clear() self.messages.clear()
self.plaintexts.clear() self.plaintexts.clear()
self.plaintext_passthrough = plaintext_passthrough self.plaintext_passthrough = plaintext_passthrough
@ -277,25 +279,25 @@ def random_policy_label():
# #
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def blockchain_alice(alice_blockchain_test_config, testerchain): def alice(alice_test_config, testerchain):
alice = alice_blockchain_test_config.produce() alice = alice_test_config.produce()
yield alice yield alice
alice.disenchant() alice.disenchant()
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def blockchain_bob(bob_blockchain_test_config, testerchain): def bob(bob_test_config, testerchain):
bob = bob_blockchain_test_config.produce() bob = bob_test_config.produce()
yield bob yield bob
bob.disenchant() bob.disenchant()
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
def lonely_ursula_maker(ursula_decentralized_test_config, testerchain): def lonely_ursula_maker(ursula_test_config, testerchain):
class _PartialUrsulaMaker: class _PartialUrsulaMaker:
_partial = partial( _partial = partial(
make_decentralized_ursulas, make_ursulas,
ursula_config=ursula_decentralized_test_config, ursula_config=ursula_test_config,
know_each_other=False, know_each_other=False,
staking_provider_addresses=testerchain.stake_providers_accounts, staking_provider_addresses=testerchain.stake_providers_accounts,
operator_addresses=testerchain.ursulas_accounts, operator_addresses=testerchain.ursulas_accounts,
@ -484,22 +486,18 @@ def staking_providers(testerchain, agency, test_registry, threshold_staking):
operator=operator_address, operator=operator_address,
transacting_power=provider_power) transacting_power=provider_power)
operator_power = TransactingPower( operator_power = TransactingPower(account=operator_address, signer=Web3Signer(testerchain.client))
account=operator_address, signer=Web3Signer(testerchain.client) operator = Operator(is_me=True,
) operator_address=operator_address,
operator = Operator( domain=TEMPORARY_DOMAIN,
is_me=True, registry=test_registry,
operator_address=operator_address, transacting_power=operator_power,
domain=TEMPORARY_DOMAIN, eth_provider_uri=testerchain.eth_provider_uri,
registry=test_registry, payment_method=SubscriptionManagerPayment(
transacting_power=operator_power, eth_provider=testerchain.eth_provider_uri,
eth_provider_uri=testerchain.eth_provider_uri, network=TEMPORARY_DOMAIN,
payment_method=SubscriptionManagerPayment( registry=test_registry)
eth_provider=testerchain.eth_provider_uri, )
network=TEMPORARY_DOMAIN,
registry=test_registry,
),
)
operator.confirm_address() # assume we always need a "pre-confirmed" operator for now. operator.confirm_address() # assume we always need a "pre-confirmed" operator for now.
# track # track
@ -509,14 +507,14 @@ def staking_providers(testerchain, agency, test_registry, threshold_staking):
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def blockchain_ursulas(testerchain, staking_providers, ursula_decentralized_test_config): def ursulas(testerchain, staking_providers, ursula_test_config):
if MOCK_KNOWN_URSULAS_CACHE: if MOCK_KNOWN_URSULAS_CACHE:
# TODO: Is this a safe assumption / test behaviour? # TODO: Is this a safe assumption / test behaviour?
# raise RuntimeError("Ursulas cache was unclear at fixture loading time. Did you use one of the ursula maker functions without cleaning up?") # raise RuntimeError("Ursulas cache was unclear at fixture loading time. Did you use one of the ursula maker functions without cleaning up?")
MOCK_KNOWN_URSULAS_CACHE.clear() MOCK_KNOWN_URSULAS_CACHE.clear()
_ursulas = make_decentralized_ursulas( _ursulas = make_ursulas(
ursula_config=ursula_decentralized_test_config, ursula_config=ursula_test_config,
staking_provider_addresses=testerchain.stake_providers_accounts, staking_provider_addresses=testerchain.stake_providers_accounts,
operator_addresses=testerchain.ursulas_accounts, operator_addresses=testerchain.ursulas_accounts,
know_each_other=True, know_each_other=True,
@ -629,9 +627,7 @@ def get_random_checksum_address():
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def fleet_of_highperf_mocked_ursulas( def fleet_of_highperf_mocked_ursulas(ursula_test_config, request, testerchain):
ursula_decentralized_test_config, request, testerchain
):
mocks = ( mocks = (
mock_cert_storage, mock_cert_storage,
@ -652,12 +648,12 @@ def fleet_of_highperf_mocked_ursulas(
for mock in mocks: for mock in mocks:
stack.enter_context(mock) stack.enter_context(mock)
_ursulas = make_decentralized_ursulas( _ursulas = make_ursulas(
ursula_config=ursula_decentralized_test_config, ursula_config=ursula_test_config,
quantity=quantity, quantity=quantity,
know_each_other=False, know_each_other=False,
staking_provider_addresses=testerchain.stake_providers_accounts, staking_provider_addresses=testerchain.stake_providers_accounts,
operator_addresses=testerchain.ursulas_accounts, operator_addresses=testerchain.ursulas_accounts
) )
all_ursulas = {u.checksum_address: u for u in _ursulas} all_ursulas = {u.checksum_address: u for u in _ursulas}
@ -675,25 +671,16 @@ def fleet_of_highperf_mocked_ursulas(
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def highperf_mocked_alice( def highperf_mocked_alice(fleet_of_highperf_mocked_ursulas, test_registry_source_manager, monkeymodule, testerchain):
fleet_of_highperf_mocked_ursulas, monkeymodule.setattr(CharacterConfiguration, 'DEFAULT_PAYMENT_NETWORK', TEMPORARY_DOMAIN)
test_registry_source_manager,
monkeymodule,
testerchain,
):
monkeymodule.setattr(
CharacterConfiguration, "DEFAULT_PAYMENT_NETWORK", TEMPORARY_DOMAIN
)
config = AliceConfiguration( config = AliceConfiguration(dev_mode=True,
dev_mode=True, domain=TEMPORARY_DOMAIN,
domain=TEMPORARY_DOMAIN, checksum_address=testerchain.alice_account,
checksum_address=testerchain.alice_account, network_middleware=MockRestMiddlewareForLargeFleetTests(),
network_middleware=MockRestMiddlewareForLargeFleetTests(), abort_on_learning_error=True,
abort_on_learning_error=True, save_metadata=False,
save_metadata=False, reload_metadata=False)
reload_metadata=False,
)
with mock_cert_storage, mock_verify_node, mock_message_verification, mock_keep_learning: with mock_cert_storage, mock_verify_node, mock_message_verification, mock_keep_learning:
alice = config.produce(known_nodes=list(fleet_of_highperf_mocked_ursulas)[:1]) alice = config.produce(known_nodes=list(fleet_of_highperf_mocked_ursulas)[:1])
@ -737,11 +724,9 @@ def click_runner():
yield runner yield runner
@pytest.fixture(scope="module") @pytest.fixture(scope='module')
def nominal_configuration_fields(test_registry_source_manager): def nominal_configuration_fields(test_registry_source_manager):
config = UrsulaConfiguration( config = UrsulaConfiguration(dev_mode=True, payment_network=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN)
dev_mode=True, payment_network=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN
)
config_fields = config.static_payload() config_fields = config.static_payload()
yield tuple(config_fields.keys()) yield tuple(config_fields.keys())
del config del config

View File

@ -12,21 +12,21 @@ real-world scenarios.
""" """
def test_sign_cleartext_and_encrypt(blockchain_alice, blockchain_bob): def test_sign_cleartext_and_encrypt(alice, bob):
""" """
Exhibit One: blockchain_alice signs the cleartext and encrypts her signature inside Exhibit One: blockchain_alice signs the cleartext and encrypts her signature inside
the ciphertext. the ciphertext.
""" """
message = b"Have you accepted my answer on StackOverflow yet?" message = b"Have you accepted my answer on StackOverflow yet?"
message_kit = blockchain_alice.encrypt_for(blockchain_alice, message) message_kit = alice.encrypt_for(alice, message)
cleartext = blockchain_alice.decrypt_message_kit(blockchain_alice, message_kit) cleartext = alice.decrypt_message_kit(alice, message_kit)
assert cleartext == message assert cleartext == message
def test_alice_can_decrypt(blockchain_alice): def test_alice_can_decrypt(alice):
label = b"boring test label" label = b"boring test label"
policy_pubkey = blockchain_alice.get_policy_encrypting_key_from_label(label) policy_pubkey = alice.get_policy_encrypting_key_from_label(label)
enrico = Enrico(policy_encrypting_key=policy_pubkey) enrico = Enrico(policy_encrypting_key=policy_pubkey)
@ -34,7 +34,5 @@ def test_alice_can_decrypt(blockchain_alice):
message_kit = enrico.encrypt_message(plaintext=message) message_kit = enrico.encrypt_message(plaintext=message)
# Interesting thing: if Alice wants to decrypt, she needs to provide the label directly. # Interesting thing: if Alice wants to decrypt, she needs to provide the label directly.
cleartexts = blockchain_alice.decrypt_message_kit( cleartexts = alice.decrypt_message_kit(label=label, message_kit=message_kit)
label=label, message_kit=message_kit
)
assert cleartexts == [message] assert cleartexts == [message]

View File

@ -15,13 +15,11 @@ def _policy_info_kwargs(enacted_policy):
) )
def test_retrieval_kit(enacted_blockchain_policy, blockchain_ursulas): def test_retrieval_kit(enacted_policy, ursulas):
messages, message_kits = make_message_kits(enacted_blockchain_policy.public_key) messages, message_kits = make_message_kits(enacted_policy.public_key)
capsule = message_kits[0].capsule capsule = message_kits[0].capsule
addresses = { addresses = {Address(ursula.canonical_address) for ursula in list(ursulas)[:2]}
Address(ursula.canonical_address) for ursula in list(blockchain_ursulas)[:2]
}
retrieval_kit = RetrievalKit(capsule, addresses, conditions=None) retrieval_kit = RetrievalKit(capsule, addresses, conditions=None)
serialized = bytes(retrieval_kit) serialized = bytes(retrieval_kit)
@ -31,78 +29,70 @@ def test_retrieval_kit(enacted_blockchain_policy, blockchain_ursulas):
assert retrieval_kit.queried_addresses == retrieval_kit_back.queried_addresses assert retrieval_kit.queried_addresses == retrieval_kit_back.queried_addresses
def test_single_retrieve(enacted_blockchain_policy, blockchain_bob, blockchain_ursulas): def test_single_retrieve(enacted_policy, bob, ursulas):
blockchain_bob.remember_node(blockchain_ursulas[0]) bob.remember_node(ursulas[0])
blockchain_bob.start_learning_loop() bob.start_learning_loop()
messages, message_kits = make_message_kits(enacted_blockchain_policy.public_key) messages, message_kits = make_message_kits(enacted_policy.public_key)
cleartexts = blockchain_bob.retrieve_and_decrypt( cleartexts = bob.retrieve_and_decrypt(
message_kits=message_kits, message_kits=message_kits,
**_policy_info_kwargs(enacted_blockchain_policy), **_policy_info_kwargs(enacted_policy),
) )
assert cleartexts == messages assert cleartexts == messages
def test_single_retrieve_conditions_set_directly_to_none( def test_single_retrieve_conditions_set_directly_to_none(enacted_policy, bob, ursulas):
enacted_blockchain_policy, blockchain_bob, blockchain_ursulas bob.start_learning_loop()
):
blockchain_bob.start_learning_loop()
message = b"plaintext1" message = b"plaintext1"
# MessageKit is created directly in this test, to ensure consistency # MessageKit is created directly in this test, to ensure consistency
message_kit = MessageKit( message_kit = MessageKit(
policy_encrypting_key=enacted_blockchain_policy.public_key, policy_encrypting_key=enacted_policy.public_key,
plaintext=message, plaintext=message,
conditions=None, conditions=None,
) )
cleartexts = blockchain_bob.retrieve_and_decrypt( cleartexts = bob.retrieve_and_decrypt(
message_kits=[message_kit], message_kits=[message_kit],
**_policy_info_kwargs(enacted_blockchain_policy), **_policy_info_kwargs(enacted_policy),
) )
assert cleartexts == [message] assert cleartexts == [message]
def test_single_retrieve_conditions_empty_list( def test_single_retrieve_conditions_empty_list(enacted_policy, bob, ursulas):
enacted_blockchain_policy, blockchain_bob, blockchain_ursulas bob.start_learning_loop()
):
blockchain_bob.start_learning_loop()
message = b"plaintext1" message = b"plaintext1"
# MessageKit is created directly in this test, to ensure consistency # MessageKit is created directly in this test, to ensure consistency
message_kit = MessageKit( message_kit = MessageKit(
policy_encrypting_key=enacted_blockchain_policy.public_key, policy_encrypting_key=enacted_policy.public_key,
plaintext=message, plaintext=message,
conditions=Conditions(json.dumps([])), conditions=Conditions(json.dumps([])),
) )
cleartexts = blockchain_bob.retrieve_and_decrypt( cleartexts = bob.retrieve_and_decrypt(
message_kits=[message_kit], message_kits=[message_kit],
**_policy_info_kwargs(enacted_blockchain_policy), **_policy_info_kwargs(enacted_policy),
) )
assert cleartexts == [message] assert cleartexts == [message]
@pytest.mark.skip( @pytest.mark.skip("This test is not working yet. It's not clear what the correct behavior is and if it's the same in nucypher-ts.")
"This test is not working yet. It's not clear what the correct behavior is and if it's the same in nucypher-ts." def test_use_external_cache(enacted_policy, bob, ursulas):
)
def test_use_external_cache(
enacted_blockchain_policy, blockchain_bob, blockchain_ursulas
):
blockchain_bob.start_learning_loop() bob.start_learning_loop()
messages, message_kits = make_message_kits(enacted_blockchain_policy.public_key) messages, message_kits = make_message_kits(enacted_policy.public_key)
ursulas = list(blockchain_ursulas) ursulas = list(ursulas)
# All Ursulas are down except for two # All Ursulas are down except for two
blockchain_bob.network_middleware = NodeIsDownMiddleware() bob.network_middleware = NodeIsDownMiddleware()
for ursula in ursulas[2:]: for ursula in ursulas[2:]:
blockchain_bob.network_middleware.node_is_down(ursula) bob.network_middleware.node_is_down(ursula)
# Fetch what we can without decrypting # Fetch what we can without decrypting
loaded_message_kits = blockchain_bob.retrieve( loaded_message_kits = bob.retrieve(
message_kits=message_kits, message_kits=message_kits,
**_policy_info_kwargs(enacted_blockchain_policy), **_policy_info_kwargs(enacted_policy),
) )
# Not enough cfrags yet # Not enough cfrags yet
@ -110,15 +100,15 @@ def test_use_external_cache(
# Now the remaining two Ursulas go down. # Now the remaining two Ursulas go down.
for ursula in ursulas[:2]: for ursula in ursulas[:2]:
blockchain_bob.network_middleware.node_is_down(ursula) bob.network_middleware.node_is_down(ursula)
# ...but one other comes up. # ...but one other comes up.
blockchain_bob.network_middleware.node_is_up(ursulas[2]) bob.network_middleware.node_is_up(ursulas[2])
# Try again, building on top of the existing cache # Try again, building on top of the existing cache
loaded_message_kits = blockchain_bob.retrieve( loaded_message_kits = bob.retrieve(
message_kits=loaded_message_kits, message_kits=loaded_message_kits,
**_policy_info_kwargs(enacted_blockchain_policy), **_policy_info_kwargs(enacted_policy),
) )
assert all(mk.is_decryptable_by_receiver() for mk in loaded_message_kits) assert all(mk.is_decryptable_by_receiver() for mk in loaded_message_kits)
@ -126,11 +116,11 @@ def test_use_external_cache(
# Should be enough cfrags now. Disconnect all Ursulas # Should be enough cfrags now. Disconnect all Ursulas
# to be sure Bob doesn't cheat and contact them again. # to be sure Bob doesn't cheat and contact them again.
for ursula in ursulas: for ursula in ursulas:
blockchain_bob.network_middleware.node_is_down(ursula) bob.network_middleware.node_is_down(ursula)
cleartexts = blockchain_bob.retrieve_and_decrypt( cleartexts = bob.retrieve_and_decrypt(
message_kits=loaded_message_kits, message_kits=loaded_message_kits,
**_policy_info_kwargs(enacted_blockchain_policy), **_policy_info_kwargs(enacted_policy),
) )
assert cleartexts == messages assert cleartexts == messages

View File

@ -13,27 +13,22 @@ from tests.utils.middleware import MockRestMiddleware
def test_blockchain_bob_full_retrieve_flow( def test_blockchain_bob_full_retrieve_flow(
blockchain_ursulas, ursulas, bob, alice, capsule_side_channel, treasure_map, enacted_policy
blockchain_bob,
blockchain_alice,
capsule_side_channel,
blockchain_treasure_map,
enacted_blockchain_policy,
): ):
for ursula in blockchain_ursulas: for ursula in ursulas:
blockchain_bob.remember_node(ursula) bob.remember_node(ursula)
# The side channel delivers all that Bob needs at this point: # The side channel delivers all that Bob needs at this point:
# - A single MessageKit, containing a Capsule # - A single MessageKit, containing a Capsule
# - A representation of the data source # - A representation of the data source
the_message_kit = capsule_side_channel() the_message_kit = capsule_side_channel()
alices_verifying_key = blockchain_alice.stamp.as_umbral_pubkey() alices_verifying_key = alice.stamp.as_umbral_pubkey()
delivered_cleartexts = blockchain_bob.retrieve_and_decrypt( delivered_cleartexts = bob.retrieve_and_decrypt(
[the_message_kit], [the_message_kit],
alice_verifying_key=alices_verifying_key, alice_verifying_key=alices_verifying_key,
encrypted_treasure_map=enacted_blockchain_policy.treasure_map, encrypted_treasure_map=enacted_policy.treasure_map,
) )
# We show that indeed this is the passage originally encrypted by the Enrico. # We show that indeed this is the passage originally encrypted by the Enrico.
@ -41,25 +36,20 @@ def test_blockchain_bob_full_retrieve_flow(
def test_bob_retrieves( def test_bob_retrieves(
blockchain_alice, alice, ursulas, certificates_tempdir, test_registry_source_manager
blockchain_ursulas,
certificates_tempdir,
test_registry_source_manager,
): ):
"""A test to show that Bob can retrieve data from Ursula""" """A test to show that Bob can retrieve data from Ursula"""
# Let's partition Ursulas in two parts # Let's partition Ursulas in two parts
a_couple_of_ursulas = list(blockchain_ursulas)[:2] a_couple_of_ursulas = list(ursulas)[:2]
rest_of_ursulas = list(blockchain_ursulas)[2:] rest_of_ursulas = list(ursulas)[2:]
# Bob becomes # Bob becomes
bob = Bob( bob = Bob(domain=TEMPORARY_DOMAIN,
domain=TEMPORARY_DOMAIN, start_learning_now=True,
start_learning_now=True, network_middleware=MockRestMiddleware(),
network_middleware=MockRestMiddleware(), abort_on_learning_error=True,
abort_on_learning_error=True, known_nodes=a_couple_of_ursulas)
known_nodes=a_couple_of_ursulas,
)
# Bob has only connected to - at most - 2 nodes. # Bob has only connected to - at most - 2 nodes.
assert sum(node.verified_node for node in bob.known_nodes) <= 2 assert sum(node.verified_node for node in bob.known_nodes) <= 2
@ -69,7 +59,7 @@ def test_bob_retrieves(
shares = NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK - 2 shares = NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK - 2
label = b'label://' + os.urandom(32) label = b'label://' + os.urandom(32)
contract_end_datetime = maya.now() + datetime.timedelta(days=5) contract_end_datetime = maya.now() + datetime.timedelta(days=5)
policy = blockchain_alice.grant( policy = alice.grant(
bob=bob, bob=bob,
label=label, label=label,
threshold=3, threshold=3,
@ -86,7 +76,7 @@ def test_bob_retrieves(
plaintext = b"What's your approach? Mississippis or what?" plaintext = b"What's your approach? Mississippis or what?"
message_kit = enrico.encrypt_message(plaintext) message_kit = enrico.encrypt_message(plaintext)
alices_verifying_key = blockchain_alice.stamp.as_umbral_pubkey() alices_verifying_key = alice.stamp.as_umbral_pubkey()
# Bob takes the message_kit and retrieves the message within # Bob takes the message_kit and retrieves the message within
delivered_cleartexts = bob.retrieve_and_decrypt([message_kit], delivered_cleartexts = bob.retrieve_and_decrypt([message_kit],
@ -103,7 +93,7 @@ def test_bob_retrieves(
assert delivered_cleartexts == cleartexts_delivered_a_second_time assert delivered_cleartexts == cleartexts_delivered_a_second_time
# Let's try retrieve again, but Alice revoked the policy. # Let's try retrieve again, but Alice revoked the policy.
receipt, failed_revocations = blockchain_alice.revoke(policy) receipt, failed_revocations = alice.revoke(policy)
assert len(failed_revocations) == 0 assert len(failed_revocations) == 0
# One thing to note here is that Bob *can* still retrieve with the cached CFrags, # One thing to note here is that Bob *can* still retrieve with the cached CFrags,
@ -117,41 +107,39 @@ def test_bob_retrieves(
def test_bob_retrieves_with_treasure_map( def test_bob_retrieves_with_treasure_map(
blockchain_bob, blockchain_ursulas, enacted_blockchain_policy, capsule_side_channel bob, ursulas, enacted_policy, capsule_side_channel
): ):
enrico = capsule_side_channel.enrico enrico = capsule_side_channel.enrico
message_kit = capsule_side_channel() message_kit = capsule_side_channel()
treasure_map = enacted_blockchain_policy.treasure_map treasure_map = enacted_policy.treasure_map
alice_verifying_key = enacted_blockchain_policy.publisher_verifying_key alice_verifying_key = enacted_policy.publisher_verifying_key
# Teach Bob about the network # Teach Bob about the network
blockchain_bob.remember_node(list(blockchain_ursulas)[0]) bob.remember_node(list(ursulas)[0])
blockchain_bob.learn_from_teacher_node(eager=True) bob.learn_from_teacher_node(eager=True)
# Deserialized treasure map # Deserialized treasure map
text1 = blockchain_bob.retrieve_and_decrypt( text1 = bob.retrieve_and_decrypt(
[message_kit], [message_kit],
alice_verifying_key=alice_verifying_key, alice_verifying_key=alice_verifying_key,
encrypted_treasure_map=treasure_map) encrypted_treasure_map=treasure_map)
assert text1 == [b"Welcome to flippering number 1."] assert text1 == [b'Welcome to flippering number 1.']
# TODO: #2813 Without kfrag and arrangement storage by nodes, # TODO: #2813 Without kfrag and arrangement storage by nodes,
@pytest.mark.skip() @pytest.mark.skip()
def test_bob_retrieves_too_late( def test_bob_retrieves_too_late(bob, ursulas, enacted_policy, capsule_side_channel):
blockchain_bob, blockchain_ursulas, enacted_blockchain_policy, capsule_side_channel
):
clock = Clock() clock = Clock()
clock.advance(time.time()) clock.advance(time.time())
clock.advance(86400 * 8) # 1 week # TODO: this is supposed to be seven days, not eight clock.advance(86400 * 8) # 1 week # TODO: this is supposed to be seven days, not eight
message_kit = capsule_side_channel() message_kit = capsule_side_channel()
treasure_map = enacted_blockchain_policy.treasure_map treasure_map = enacted_policy.treasure_map
alice_verifying_key = enacted_blockchain_policy.publisher_verifying_key alice_verifying_key = enacted_policy.publisher_verifying_key
# with pytest.raises(Ursula.NotEnoughUrsulas): # with pytest.raises(Ursula.NotEnoughUrsulas):
blockchain_bob.retrieve_and_decrypt( bob.retrieve_and_decrypt(
[message_kit], [message_kit],
alice_verifying_key=alice_verifying_key, alice_verifying_key=alice_verifying_key,
encrypted_treasure_map=treasure_map encrypted_treasure_map=treasure_map

View File

@ -15,15 +15,13 @@ def _policy_info_kwargs(enacted_policy):
) )
def test_single_retrieve_with_truthy_conditions( def test_single_retrieve_with_truthy_conditions(enacted_policy, bob, ursulas, mocker):
enacted_blockchain_policy, blockchain_bob, blockchain_ursulas, mocker
):
from nucypher_core import MessageKit from nucypher_core import MessageKit
reencrypt_spy = mocker.spy(Ursula, '_reencrypt') reencrypt_spy = mocker.spy(Ursula, '_reencrypt')
blockchain_bob.remember_node(blockchain_ursulas[0]) bob.remember_node(ursulas[0])
blockchain_bob.start_learning_loop() bob.start_learning_loop()
conditions = [ conditions = [
{'returnValueTest': {'value': '0', 'comparator': '>'}, 'method': 'timelock'}, {'returnValueTest': {'value': '0', 'comparator': '>'}, 'method': 'timelock'},
@ -32,22 +30,18 @@ def test_single_retrieve_with_truthy_conditions(
] ]
json_conditions = json.dumps(conditions) json_conditions = json.dumps(conditions)
rust_conditions = Conditions(json_conditions) rust_conditions = Conditions(json_conditions)
message_kits = [ message_kits = [MessageKit(enacted_policy.public_key, b"lab", rust_conditions)]
MessageKit(enacted_blockchain_policy.public_key, b"lab", rust_conditions)
]
cleartexts = blockchain_bob.retrieve_and_decrypt( cleartexts = bob.retrieve_and_decrypt(
message_kits=message_kits, message_kits=message_kits,
**_policy_info_kwargs(enacted_blockchain_policy), **_policy_info_kwargs(enacted_policy),
) )
assert b'lab' in cleartexts assert b'lab' in cleartexts
assert reencrypt_spy.call_count == enacted_blockchain_policy.threshold assert reencrypt_spy.call_count == enacted_policy.threshold
def test_single_retrieve_with_falsy_conditions( def test_single_retrieve_with_falsy_conditions(enacted_policy, bob, ursulas, mocker):
enacted_blockchain_policy, blockchain_bob, blockchain_ursulas, mocker
):
from nucypher_core import MessageKit from nucypher_core import MessageKit
reencrypt_spy = mocker.spy(Ursula, '_reencrypt') reencrypt_spy = mocker.spy(Ursula, '_reencrypt')
@ -59,16 +53,14 @@ def test_single_retrieve_with_falsy_conditions(
[{'returnValueTest': {'value': '0', 'comparator': '>'}, 'method': 'timelock'}] [{'returnValueTest': {'value': '0', 'comparator': '>'}, 'method': 'timelock'}]
)) ))
blockchain_bob.start_learning_loop() bob.start_learning_loop()
message_kits = [ message_kits = [MessageKit(enacted_policy.public_key, b"radio", conditions)]
MessageKit(enacted_blockchain_policy.public_key, b"radio", conditions)
]
with pytest.raises(Ursula.NotEnoughUrsulas): with pytest.raises(Ursula.NotEnoughUrsulas):
blockchain_bob.retrieve_and_decrypt( bob.retrieve_and_decrypt(
message_kits=message_kits, message_kits=message_kits,
**_policy_info_kwargs(enacted_blockchain_policy), **_policy_info_kwargs(enacted_policy),
) )
reencrypt_spy.assert_not_called() reencrypt_spy.assert_not_called()

View File

@ -10,26 +10,22 @@ from nucypher_core import EncryptedKeyFrag, RevocationOrder
from nucypher.characters.lawful import Enrico from nucypher.characters.lawful import Enrico
def test_grant(blockchain_alice, blockchain_bob, blockchain_ursulas): def test_grant(alice, bob, ursulas):
# Setup the policy details # Setup the policy details
threshold, shares = 2, 3 threshold, shares = 2, 3
policy_end_datetime = maya.now() + datetime.timedelta(days=5) policy_end_datetime = maya.now() + datetime.timedelta(days=5)
label = b"this_is_the_path_to_which_access_is_being_granted" label = b"this_is_the_path_to_which_access_is_being_granted"
# Create the Policy, granting access to Bob # Create the Policy, granting access to Bob
policy = blockchain_alice.grant( policy = alice.grant(
blockchain_bob, bob, label, threshold=threshold, shares=shares, expiration=policy_end_datetime
label,
threshold=threshold,
shares=shares,
expiration=policy_end_datetime,
) )
# Check Alice's active policies # Check Alice's active policies
assert policy.hrac in blockchain_alice.active_policies assert policy.hrac in alice.active_policies
assert blockchain_alice.active_policies[policy.hrac] == policy assert alice.active_policies[policy.hrac] == policy
treasure_map = blockchain_bob._decrypt_treasure_map( treasure_map = bob._decrypt_treasure_map(
policy.treasure_map, policy.publisher_verifying_key policy.treasure_map, policy.publisher_verifying_key
) )
@ -37,7 +33,7 @@ def test_grant(blockchain_alice, blockchain_bob, blockchain_ursulas):
assert len(treasure_map.destinations) == shares assert len(treasure_map.destinations) == shares
# Let's look at the destinations. # Let's look at the destinations.
for ursula in blockchain_ursulas: for ursula in ursulas:
if ursula.canonical_address in treasure_map.destinations: if ursula.canonical_address in treasure_map.destinations:
kfrag_kit = treasure_map.destinations[ursula.canonical_address] kfrag_kit = treasure_map.destinations[ursula.canonical_address]
@ -46,7 +42,7 @@ def test_grant(blockchain_alice, blockchain_bob, blockchain_ursulas):
assert isinstance(kfrag_kit, EncryptedKeyFrag) assert isinstance(kfrag_kit, EncryptedKeyFrag)
def test_blockchain_alice_can_decrypt(blockchain_alice, blockchain_bob): def test_blockchain_alice_can_decrypt(alice, bob):
""" """
Test that alice can decrypt data encrypted by an enrico Test that alice can decrypt data encrypted by an enrico
for her own derived policy pubkey. for her own derived policy pubkey.
@ -57,8 +53,8 @@ def test_blockchain_alice_can_decrypt(blockchain_alice, blockchain_bob):
policy_end_datetime = maya.now() + datetime.timedelta(days=5) policy_end_datetime = maya.now() + datetime.timedelta(days=5)
label = b"this_is_the_path_to_which_access_is_being_granted" label = b"this_is_the_path_to_which_access_is_being_granted"
policy = blockchain_alice.create_policy( policy = alice.create_policy(
bob=blockchain_bob, bob=bob,
label=label, label=label,
threshold=threshold, threshold=threshold,
shares=shares, shares=shares,
@ -66,7 +62,7 @@ def test_blockchain_alice_can_decrypt(blockchain_alice, blockchain_bob):
) )
enrico = Enrico.from_alice( enrico = Enrico.from_alice(
blockchain_alice, alice,
policy.label, policy.label,
) )
plaintext = b"this is the first thing i'm encrypting ever." plaintext = b"this is the first thing i'm encrypting ever."
@ -75,7 +71,7 @@ def test_blockchain_alice_can_decrypt(blockchain_alice, blockchain_bob):
message_kit = enrico.encrypt_message(plaintext) message_kit = enrico.encrypt_message(plaintext)
# decrypt the data # decrypt the data
decrypted_data = blockchain_alice.decrypt_message_kit( decrypted_data = alice.decrypt_message_kit(
label=policy.label, label=policy.label,
message_kit=message_kit, message_kit=message_kit,
) )
@ -84,18 +80,14 @@ def test_blockchain_alice_can_decrypt(blockchain_alice, blockchain_bob):
@pytest.mark.skip("Needs rework post-TMcKF") # TODO: Implement offchain revocation. @pytest.mark.skip("Needs rework post-TMcKF") # TODO: Implement offchain revocation.
@pytest.mark.usefixtures("blockchain_ursulas") @pytest.mark.usefixtures('blockchain_ursulas')
def test_revocation(blockchain_alice, blockchain_bob): def test_revocation(alice, bob):
threshold, shares = 2, 3 threshold, shares = 2, 3
policy_end_datetime = maya.now() + datetime.timedelta(days=5) policy_end_datetime = maya.now() + datetime.timedelta(days=5)
label = b"revocation test" label = b"revocation test"
policy = blockchain_alice.grant( policy = alice.grant(
blockchain_bob, bob, label, threshold=threshold, shares=shares, expiration=policy_end_datetime
label,
threshold=threshold,
shares=shares,
expiration=policy_end_datetime,
) )
for node_id, encrypted_kfrag in policy.treasure_map: for node_id, encrypted_kfrag in policy.treasure_map:
@ -103,7 +95,7 @@ def test_revocation(blockchain_alice, blockchain_bob):
# Test revocation kit's signatures # Test revocation kit's signatures
for revocation in policy.revocation_kit: for revocation in policy.revocation_kit:
assert revocation.verify_signature(blockchain_alice.stamp.as_umbral_pubkey()) assert revocation.verify_signature(alice.stamp.as_umbral_pubkey())
# Test Revocation deserialization # Test Revocation deserialization
revocation = policy.revocation_kit[node_id] revocation = policy.revocation_kit[node_id]
@ -112,9 +104,9 @@ def test_revocation(blockchain_alice, blockchain_bob):
assert deserialized_revocation == revocation assert deserialized_revocation == revocation
# Attempt to revoke the new policy # Attempt to revoke the new policy
receipt, failed_revocations = blockchain_alice.revoke(policy) receipt, failed_revocations = alice.revoke(policy)
assert len(failed_revocations) == 0 assert len(failed_revocations) == 0
# Try to revoke the already revoked policy # Try to revoke the already revoked policy
receipt, already_revoked = blockchain_alice.revoke(policy) receipt, already_revoked = alice.revoke(policy)
assert len(already_revoked) == 3 assert len(already_revoked) == 3

View File

@ -18,8 +18,8 @@ def test_new_ursula_announces_herself(lonely_ursula_maker):
assert ursula_in_a_house in ursula_with_a_mouse.known_nodes assert ursula_in_a_house in ursula_with_a_mouse.known_nodes
def test_node_deployer(blockchain_ursulas): def test_node_deployer(ursulas):
for ursula in blockchain_ursulas: for ursula in ursulas:
deployer = ursula.get_deployer() deployer = ursula.get_deployer()
assert deployer.options['https_port'] == ursula.rest_information()[0].port assert deployer.options['https_port'] == ursula.rest_information()[0].port
assert deployer.application == ursula.rest_app assert deployer.application == ursula.rest_app

View File

@ -90,12 +90,14 @@ def test_get_nucypher_password(mock_stdin, mock_account, confirm, capsys):
assert prompt in captured.out assert prompt in captured.out
def test_unlock_nucypher_keystore_invalid_password(mocker, def test_unlock_nucypher_keystore_invalid_password(
test_emitter, mocker,
alice_blockchain_test_config, test_emitter,
capsys, alice_test_config,
tmpdir, capsys,
test_registry_source_manager): tmpdir,
test_registry_source_manager,
):
# Setup # Setup
mocker.patch.object(passwords, 'secret_box_decrypt', side_effect=SecretBoxAuthenticationError) mocker.patch.object(passwords, 'secret_box_decrypt', side_effect=SecretBoxAuthenticationError)
@ -104,19 +106,26 @@ def test_unlock_nucypher_keystore_invalid_password(mocker,
return_value=False, return_value=False,
new_callable=mocker.PropertyMock) new_callable=mocker.PropertyMock)
keystore = Keystore.generate(password=INSECURE_DEVELOPMENT_PASSWORD, keystore_dir=tmpdir) keystore = Keystore.generate(password=INSECURE_DEVELOPMENT_PASSWORD, keystore_dir=tmpdir)
alice_blockchain_test_config.attach_keystore(keystore) alice_test_config.attach_keystore(keystore)
# Test # Test
with pytest.raises(Keystore.AuthenticationFailed): with pytest.raises(Keystore.AuthenticationFailed):
unlock_nucypher_keystore(emitter=test_emitter, unlock_nucypher_keystore(
password=INSECURE_DEVELOPMENT_PASSWORD+'typo', emitter=test_emitter,
character_configuration=alice_blockchain_test_config) password=INSECURE_DEVELOPMENT_PASSWORD + "typo",
character_configuration=alice_test_config,
)
captured = capsys.readouterr() captured = capsys.readouterr()
assert DECRYPTING_CHARACTER_KEYSTORE.format(name=alice_blockchain_test_config.NAME.capitalize()) in captured.out assert (
DECRYPTING_CHARACTER_KEYSTORE.format(name=alice_test_config.NAME.capitalize())
in captured.out
)
def test_unlock_nucypher_keystore_dev_mode(mocker, test_emitter, capsys, alice_blockchain_test_config, tmpdir): def test_unlock_nucypher_keystore_dev_mode(
mocker, test_emitter, capsys, alice_test_config, tmpdir
):
# Setup # Setup
unlock_spy = mocker.spy(Keystore, 'unlock') unlock_spy = mocker.spy(Keystore, 'unlock')
@ -125,26 +134,27 @@ def test_unlock_nucypher_keystore_dev_mode(mocker, test_emitter, capsys, alice_b
return_value=True, return_value=True,
new_callable=mocker.PropertyMock) new_callable=mocker.PropertyMock)
keystore = Keystore.generate(password=INSECURE_DEVELOPMENT_PASSWORD, keystore_dir=tmpdir) keystore = Keystore.generate(password=INSECURE_DEVELOPMENT_PASSWORD, keystore_dir=tmpdir)
alice_blockchain_test_config.attach_keystore(keystore) alice_test_config.attach_keystore(keystore)
result = unlock_nucypher_keystore(emitter=test_emitter, result = unlock_nucypher_keystore(
password=INSECURE_DEVELOPMENT_PASSWORD, emitter=test_emitter,
character_configuration=alice_blockchain_test_config) password=INSECURE_DEVELOPMENT_PASSWORD,
character_configuration=alice_test_config,
)
assert result assert result
output = capsys.readouterr().out output = capsys.readouterr().out
message = DECRYPTING_CHARACTER_KEYSTORE.format(name=alice_blockchain_test_config.NAME.capitalize()) message = DECRYPTING_CHARACTER_KEYSTORE.format(
name=alice_test_config.NAME.capitalize()
)
assert message in output assert message in output
unlock_spy.assert_not_called() unlock_spy.assert_not_called()
def test_unlock_nucypher_keystore(mocker, def test_unlock_nucypher_keystore(
test_emitter, mocker, test_emitter, capsys, alice_test_config, patch_keystore, tmpdir
capsys, ):
alice_blockchain_test_config,
patch_keystore,
tmpdir):
# Setup # Setup
# Do not test "real" unlocking here, just the plumbing # Do not test "real" unlocking here, just the plumbing
@ -155,15 +165,19 @@ def test_unlock_nucypher_keystore(mocker,
new_callable=mocker.PropertyMock) new_callable=mocker.PropertyMock)
mocker.patch.object(Mnemonic, 'detect_language', return_value='english') mocker.patch.object(Mnemonic, 'detect_language', return_value='english')
keystore = Keystore.generate(password=INSECURE_DEVELOPMENT_PASSWORD, keystore_dir=tmpdir) keystore = Keystore.generate(password=INSECURE_DEVELOPMENT_PASSWORD, keystore_dir=tmpdir)
alice_blockchain_test_config.attach_keystore(keystore) alice_test_config.attach_keystore(keystore)
result = unlock_nucypher_keystore(emitter=test_emitter, result = unlock_nucypher_keystore(
password=INSECURE_DEVELOPMENT_PASSWORD, emitter=test_emitter,
character_configuration=alice_blockchain_test_config) password=INSECURE_DEVELOPMENT_PASSWORD,
character_configuration=alice_test_config,
)
assert result assert result
captured = capsys.readouterr() captured = capsys.readouterr()
message = DECRYPTING_CHARACTER_KEYSTORE.format(name=alice_blockchain_test_config.NAME.capitalize()) message = DECRYPTING_CHARACTER_KEYSTORE.format(
name=alice_test_config.NAME.capitalize()
)
assert message in captured.out assert message in captured.out
unlock_spy.assert_called_once_with(password=INSECURE_DEVELOPMENT_PASSWORD) unlock_spy.assert_called_once_with(password=INSECURE_DEVELOPMENT_PASSWORD)

View File

@ -1,8 +1,7 @@
from pathlib import Path
import click import click
import pytest import pytest
from pathlib import Path
from nucypher.cli.actions import configure from nucypher.cli.actions import configure
from nucypher.cli.actions.configure import ( from nucypher.cli.actions.configure import (
@ -10,16 +9,16 @@ from nucypher.cli.actions.configure import (
forget, forget,
get_or_update_configuration, get_or_update_configuration,
handle_invalid_configuration_file, handle_invalid_configuration_file,
handle_missing_configuration_file handle_missing_configuration_file,
) )
from nucypher.cli.literature import ( from nucypher.cli.literature import (
CONFIRM_FORGET_NODES,
INVALID_CONFIGURATION_FILE_WARNING, INVALID_CONFIGURATION_FILE_WARNING,
INVALID_JSON_IN_CONFIGURATION_WARNING, INVALID_JSON_IN_CONFIGURATION_WARNING,
MISSING_CONFIGURATION_FILE, MISSING_CONFIGURATION_FILE,
SUCCESSFUL_DESTRUCTION, SUCCESSFUL_DESTRUCTION,
SUCCESSFUL_UPDATE_CONFIGURATION_VALUES,
CONFIRM_FORGET_NODES,
SUCCESSFUL_FORGET_NODES, SUCCESSFUL_FORGET_NODES,
SUCCESSFUL_UPDATE_CONFIGURATION_VALUES,
) )
from nucypher.config.base import CharacterConfiguration from nucypher.config.base import CharacterConfiguration
from tests.constants import YES from tests.constants import YES
@ -34,9 +33,9 @@ BAD_CONFIG_FILE_CONTENTS = (
# For parameterized fixture # For parameterized fixture
CONFIGS = [ CONFIGS = [
'alice_blockchain_test_config', "alice_test_config",
'bob_blockchain_test_config', "bob_test_config",
'ursula_decentralized_test_config', "ursula_test_config",
] ]
@ -67,10 +66,10 @@ def config(request, mocker):
mocker.resetall() # dont carry over context between functions mocker.resetall() # dont carry over context between functions
def test_forget_cli_action(alice_blockchain_test_config, test_emitter, mock_stdin, mocker, capsys): def test_forget_cli_action(alice_test_config, test_emitter, mock_stdin, mocker, capsys):
mock_forget = mocker.patch.object(CharacterConfiguration, 'forget_nodes') mock_forget = mocker.patch.object(CharacterConfiguration, 'forget_nodes')
mock_stdin.line(YES) mock_stdin.line(YES)
forget(emitter=test_emitter, configuration=alice_blockchain_test_config) forget(emitter=test_emitter, configuration=alice_test_config)
mock_forget.assert_called_once() mock_forget.assert_called_once()
assert mock_stdin.empty() assert mock_stdin.empty()
captured = capsys.readouterr() captured = capsys.readouterr()

View File

@ -1,23 +1,24 @@
from pathlib import Path
import os import os
from pathlib import Path
import click import click
import pytest import pytest
from nucypher.cli.actions.select import select_config_file from nucypher.cli.actions.select import select_config_file
from nucypher.cli.literature import NO_CONFIGURATIONS_ON_DISK, DEFAULT_TO_LONE_CONFIG_FILE from nucypher.cli.literature import (
DEFAULT_TO_LONE_CONFIG_FILE,
NO_CONFIGURATIONS_ON_DISK,
)
def test_select_config_file_with_no_config_files(test_emitter, def test_select_config_file_with_no_config_files(
capsys, test_emitter, capsys, alice_test_config, temp_dir_path
alice_blockchain_test_config, ):
temp_dir_path):
# Setup # Setup
config_class = alice_blockchain_test_config config_class = alice_test_config
# Prove there are no config files on the disk. # Prove there are no config files on the disk.
assert not list(temp_dir_path.iterdir()) assert not list(temp_dir_path.iterdir())
@ -33,14 +34,12 @@ def test_select_config_file_with_no_config_files(test_emitter,
assert message in captured.out assert message in captured.out
def test_auto_select_config_file(test_emitter, def test_auto_select_config_file(
capsys, test_emitter, capsys, alice_test_config, temp_dir_path, mock_stdin
alice_blockchain_test_config, ):
temp_dir_path,
mock_stdin):
"""Only one configuration was found, so it was chosen automatically""" """Only one configuration was found, so it was chosen automatically"""
config_class = alice_blockchain_test_config config_class = alice_test_config
config_path = temp_dir_path / config_class.generate_filename() config_path = temp_dir_path / config_class.generate_filename()
# Make one configuration # Make one configuration
@ -63,18 +62,20 @@ def test_auto_select_config_file(test_emitter,
config_file=str(config_path)) in captured.out config_file=str(config_path)) in captured.out
def test_interactive_select_config_file(test_emitter, def test_interactive_select_config_file(
capsys, test_emitter,
alice_blockchain_test_config, capsys,
temp_dir_path, alice_test_config,
mock_stdin, temp_dir_path,
mock_accounts, mock_stdin,
patch_keystore): mock_accounts,
patch_keystore,
):
"""Multiple configurations found - Prompt the user for a selection""" """Multiple configurations found - Prompt the user for a selection"""
user_input = 0 user_input = 0
config = alice_blockchain_test_config config = alice_test_config
config_class = config.__class__ config_class = config.__class__
# Make one configuration... # Make one configuration...

View File

@ -13,7 +13,7 @@ from tests.utils.middleware import MockRestMiddleware
def test_alices_powers_are_persistent( def test_alices_powers_are_persistent(
blockchain_ursulas, temp_dir_path, test_registry_source_manager, testerchain ursulas, temp_dir_path, test_registry_source_manager, testerchain
): ):
# Create a non-learning AliceConfiguration # Create a non-learning AliceConfiguration
config_root = temp_dir_path / 'nucypher-custom-alice-config' config_root = temp_dir_path / 'nucypher-custom-alice-config'
@ -26,7 +26,7 @@ def test_alices_powers_are_persistent(
start_learning_now=False, start_learning_now=False,
save_metadata=False, save_metadata=False,
reload_metadata=False, reload_metadata=False,
known_nodes=blockchain_ursulas, known_nodes=ursulas,
) )
# Generate keys and write them the disk # Generate keys and write them the disk
@ -57,11 +57,7 @@ def test_alices_powers_are_persistent(
threshold, shares = 3, 4 threshold, shares = 3, 4
policy_end_datetime = maya.now() + datetime.timedelta(days=5) policy_end_datetime = maya.now() + datetime.timedelta(days=5)
bob = Bob( bob = Bob(start_learning_now=False, domain=TEMPORARY_DOMAIN, network_middleware=MockRestMiddleware())
start_learning_now=False,
domain=TEMPORARY_DOMAIN,
network_middleware=MockRestMiddleware(),
)
bob_policy = alice.grant(bob, label, threshold=threshold, shares=shares, expiration=policy_end_datetime) bob_policy = alice.grant(bob, label, threshold=threshold, shares=shares, expiration=policy_end_datetime)
@ -86,7 +82,7 @@ def test_alices_powers_are_persistent(
network_middleware=MockRestMiddleware(), network_middleware=MockRestMiddleware(),
start_learning_now=False, start_learning_now=False,
config_root=config_root, config_root=config_root,
known_nodes=blockchain_ursulas, known_nodes=ursulas,
) )
# Alice unlocks her restored keystore from disk # Alice unlocks her restored keystore from disk
@ -98,11 +94,7 @@ def test_alices_powers_are_persistent(
assert alices_receiving_key == new_alice.public_keys(DecryptingPower) assert alices_receiving_key == new_alice.public_keys(DecryptingPower)
# Bob's eldest brother, Roberto, appears too # Bob's eldest brother, Roberto, appears too
roberto = Bob( roberto = Bob(domain=TEMPORARY_DOMAIN, start_learning_now=False, network_middleware=MockRestMiddleware())
domain=TEMPORARY_DOMAIN,
start_learning_now=False,
network_middleware=MockRestMiddleware(),
)
# Alice creates a new policy for Roberto. Note how all the parameters # Alice creates a new policy for Roberto. Note how all the parameters
# except for the label (i.e., recipient, m, n, policy_end) are different # except for the label (i.e., recipient, m, n, policy_end) are different

View File

@ -5,7 +5,7 @@ from nucypher.acumen.perception import FleetSensor
from nucypher.characters.lawful import Ursula from nucypher.characters.lawful import Ursula
from nucypher.config.storages import LocalFileBasedNodeStorage from nucypher.config.storages import LocalFileBasedNodeStorage
from nucypher.network.nodes import TEACHER_NODES from nucypher.network.nodes import TEACHER_NODES
from tests.utils.ursula import make_decentralized_ursulas from tests.utils.ursula import make_ursulas
def test_learner_learns_about_domains_separately(lonely_ursula_maker, caplog): def test_learner_learns_about_domains_separately(lonely_ursula_maker, caplog):
@ -52,11 +52,9 @@ def test_learner_restores_metadata_from_storage(lonely_ursula_maker, tmpdir):
root = tmpdir.mkdir("known_nodes") root = tmpdir.mkdir("known_nodes")
metadata = root.mkdir("metadata") metadata = root.mkdir("metadata")
certs = root.mkdir("certs") certs = root.mkdir("certs")
old_storage = LocalFileBasedNodeStorage( old_storage = LocalFileBasedNodeStorage(metadata_dir=Path(metadata),
metadata_dir=Path(metadata), certificates_dir=Path(certs),
certificates_dir=Path(certs), storage_root=Path(root))
storage_root=Path(root),
)
# Use the ursula maker with this storage so it's populated with nodes from one domain # Use the ursula maker with this storage so it's populated with nodes from one domain
_some_ursulas = lonely_ursula_maker(domain="fistro", _some_ursulas = lonely_ursula_maker(domain="fistro",
@ -85,19 +83,19 @@ def test_learner_restores_metadata_from_storage(lonely_ursula_maker, tmpdir):
def test_learner_ignores_stored_nodes_from_other_domains( def test_learner_ignores_stored_nodes_from_other_domains(
lonely_ursula_maker, tmpdir, testerchain, ursula_decentralized_test_config lonely_ursula_maker, tmpdir, testerchain, ursula_test_config
): ):
learner, other_staker = make_decentralized_ursulas( learner, other_staker = make_ursulas(
ursula_decentralized_test_config, ursula_test_config,
domain="call-it-mainnet", domain="call-it-mainnet",
quantity=2, quantity=2,
know_each_other=True, know_each_other=True,
staking_provider_addresses=testerchain.stake_providers_accounts[:2], staking_provider_addresses=testerchain.stake_providers_accounts[:2],
operator_addresses=testerchain.ursulas_accounts[:2], operator_addresses=testerchain.ursulas_accounts[:2],
) )
pest, *other_ursulas_from_the_wrong_side_of_the_tracks = make_decentralized_ursulas( pest, *other_ursulas_from_the_wrong_side_of_the_tracks = make_ursulas(
ursula_decentralized_test_config, ursula_test_config,
domain="i-dunno-testt-maybe", domain="i-dunno-testt-maybe",
quantity=5, quantity=5,
know_each_other=True, know_each_other=True,
@ -140,12 +138,7 @@ def test_learner_with_empty_storage_uses_fallback_nodes(lonely_ursula_maker, moc
def test_learner_uses_both_nodes_from_storage_and_fallback_nodes( def test_learner_uses_both_nodes_from_storage_and_fallback_nodes(
lonely_ursula_maker, lonely_ursula_maker, tmpdir, mocker, test_registry, ursula_test_config, testerchain
tmpdir,
mocker,
test_registry,
ursula_decentralized_test_config,
testerchain,
): ):
domain = "learner-domain" domain = "learner-domain"
mocker.patch.dict(TEACHER_NODES, {domain: ("teacher-uri",)}, clear=True) mocker.patch.dict(TEACHER_NODES, {domain: ("teacher-uri",)}, clear=True)
@ -154,15 +147,13 @@ def test_learner_uses_both_nodes_from_storage_and_fallback_nodes(
root = tmpdir.mkdir("known_nodes") root = tmpdir.mkdir("known_nodes")
metadata = root.mkdir("metadata") metadata = root.mkdir("metadata")
certs = root.mkdir("certs") certs = root.mkdir("certs")
node_storage = LocalFileBasedNodeStorage( node_storage = LocalFileBasedNodeStorage(metadata_dir=Path(metadata),
metadata_dir=Path(metadata), certificates_dir=Path(certs),
certificates_dir=Path(certs), storage_root=Path(root))
storage_root=Path(root),
)
# Create some nodes and persist them to local storage # Create some nodes and persist them to local storage
other_nodes = make_decentralized_ursulas( other_nodes = make_ursulas(
ursula_decentralized_test_config, ursula_test_config,
domain=domain, domain=domain,
node_storage=node_storage, node_storage=node_storage,
know_each_other=True, know_each_other=True,

View File

@ -3,13 +3,13 @@ from functools import partial
from constant_sorrow.constants import FLEET_STATES_MATCH from constant_sorrow.constants import FLEET_STATES_MATCH
def test_all_nodes_have_same_fleet_state(blockchain_ursulas): def test_all_nodes_have_same_fleet_state(ursulas):
checksums = [u.known_nodes.checksum for u in blockchain_ursulas] checksums = [u.known_nodes.checksum for u in ursulas]
assert len(set(checksums)) == 1 # There is only 1 unique value. assert len(set(checksums)) == 1 # There is only 1 unique value.
def test_teacher_nodes_cycle(blockchain_ursulas): def test_teacher_nodes_cycle(ursulas):
ursula = list(blockchain_ursulas)[0] ursula = list(ursulas)[0]
# Before we start learning, Ursula has no teacher. # Before we start learning, Ursula has no teacher.
assert ursula._current_teacher_node is None assert ursula._current_teacher_node is None
@ -25,9 +25,9 @@ def test_teacher_nodes_cycle(blockchain_ursulas):
assert first_teacher != second_teacher assert first_teacher != second_teacher
def test_nodes_with_equal_fleet_state_do_not_send_anew(blockchain_ursulas): def test_nodes_with_equal_fleet_state_do_not_send_anew(ursulas):
some_ursula = list(blockchain_ursulas)[2] some_ursula = list(ursulas)[2]
another_ursula = list(blockchain_ursulas)[3] another_ursula = list(ursulas)[3]
# These two have the same fleet state. # These two have the same fleet state.
assert some_ursula.known_nodes.checksum == another_ursula.known_nodes.checksum assert some_ursula.known_nodes.checksum == another_ursula.known_nodes.checksum
@ -36,13 +36,13 @@ def test_nodes_with_equal_fleet_state_do_not_send_anew(blockchain_ursulas):
assert result is FLEET_STATES_MATCH assert result is FLEET_STATES_MATCH
def test_old_state_is_preserved(blockchain_ursulas, lonely_ursula_maker): def test_old_state_is_preserved(ursulas, lonely_ursula_maker):
lonely_learner = lonely_ursula_maker().pop() lonely_learner = lonely_ursula_maker().pop()
# This Ursula doesn't know about any nodes. # This Ursula doesn't know about any nodes.
assert len(lonely_learner.known_nodes) == 0 assert len(lonely_learner.known_nodes) == 0
some_ursula_in_the_fleet = list(blockchain_ursulas)[0] some_ursula_in_the_fleet = list(ursulas)[0]
lonely_learner.remember_node(some_ursula_in_the_fleet) lonely_learner.remember_node(some_ursula_in_the_fleet)
checksum_after_learning_one = lonely_learner.known_nodes.checksum checksum_after_learning_one = lonely_learner.known_nodes.checksum
assert some_ursula_in_the_fleet in lonely_learner.known_nodes assert some_ursula_in_the_fleet in lonely_learner.known_nodes
@ -50,7 +50,7 @@ def test_old_state_is_preserved(blockchain_ursulas, lonely_ursula_maker):
assert len(lonely_learner.known_nodes) == 1 assert len(lonely_learner.known_nodes) == 1
assert lonely_learner.known_nodes.population == 2 assert lonely_learner.known_nodes.population == 2
another_ursula_in_the_fleet = list(blockchain_ursulas)[1] another_ursula_in_the_fleet = list(ursulas)[1]
lonely_learner.remember_node(another_ursula_in_the_fleet) lonely_learner.remember_node(another_ursula_in_the_fleet)
checksum_after_learning_two = lonely_learner.known_nodes.checksum checksum_after_learning_two = lonely_learner.known_nodes.checksum
assert some_ursula_in_the_fleet in lonely_learner.known_nodes assert some_ursula_in_the_fleet in lonely_learner.known_nodes
@ -71,7 +71,7 @@ def test_old_state_is_preserved(blockchain_ursulas, lonely_ursula_maker):
assert second_state.checksum == checksum_after_learning_two assert second_state.checksum == checksum_after_learning_two
def test_state_is_recorded_after_learning(blockchain_ursulas, lonely_ursula_maker): def test_state_is_recorded_after_learning(ursulas, lonely_ursula_maker):
""" """
Similar to above, but this time we show that the Learner records a new state only once after learning Similar to above, but this time we show that the Learner records a new state only once after learning
about a bunch of nodes. about a bunch of nodes.
@ -83,7 +83,7 @@ def test_state_is_recorded_after_learning(blockchain_ursulas, lonely_ursula_make
# This Ursula doesn't know about any nodes. # This Ursula doesn't know about any nodes.
assert len(lonely_learner.known_nodes) == 0 assert len(lonely_learner.known_nodes) == 0
some_ursula_in_the_fleet = list(blockchain_ursulas)[0] some_ursula_in_the_fleet = list(ursulas)[0]
lonely_learner.remember_node(some_ursula_in_the_fleet) lonely_learner.remember_node(some_ursula_in_the_fleet)
# Archived states at this point: # Archived states at this point:
# - inital one (empty, Ursula's metadata is not ready yet, no known nodes) # - inital one (empty, Ursula's metadata is not ready yet, no known nodes)
@ -103,16 +103,16 @@ def test_state_is_recorded_after_learning(blockchain_ursulas, lonely_ursula_make
assert len(states) == 4 assert len(states) == 4
# When we ran learn_from_teacher_node, we also loaded the rest of the fleet. # When we ran learn_from_teacher_node, we also loaded the rest of the fleet.
assert states[-1].population == len(blockchain_ursulas) + 1 assert states[-1].population == len(ursulas) + 1
def test_teacher_records_new_fleet_state_upon_hearing_about_new_node( def test_teacher_records_new_fleet_state_upon_hearing_about_new_node(
blockchain_ursulas, lonely_ursula_maker ursulas, lonely_ursula_maker
): ):
_lonely_ursula_maker = partial(lonely_ursula_maker, quantity=1) _lonely_ursula_maker = partial(lonely_ursula_maker, quantity=1)
lonely_learner = _lonely_ursula_maker().pop() lonely_learner = _lonely_ursula_maker().pop()
some_ursula_in_the_fleet = list(blockchain_ursulas)[0] some_ursula_in_the_fleet = list(ursulas)[0]
lonely_learner.remember_node(some_ursula_in_the_fleet) lonely_learner.remember_node(some_ursula_in_the_fleet)

View File

@ -12,24 +12,24 @@ from tests.utils.middleware import NodeIsDownMiddleware
def test_alice_can_grant_even_when_the_first_nodes_she_tries_are_down( def test_alice_can_grant_even_when_the_first_nodes_she_tries_are_down(
blockchain_alice, blockchain_bob, blockchain_ursulas alice, bob, ursulas
): ):
threshold, shares = 2, 3 threshold, shares = 2, 3
policy_end_datetime = maya.now() + datetime.timedelta(days=5) policy_end_datetime = maya.now() + datetime.timedelta(days=5)
label = b"this_is_the_path_to_which_access_is_being_granted" label = b"this_is_the_path_to_which_access_is_being_granted"
blockchain_alice.known_nodes.current_state._nodes = {} alice.known_nodes.current_state._nodes = {}
blockchain_alice.network_middleware = NodeIsDownMiddleware() alice.network_middleware = NodeIsDownMiddleware()
# OK, her first and only node is down. # OK, her first and only node is down.
down_node = list(blockchain_ursulas)[0] down_node = list(ursulas)[0]
blockchain_alice.remember_node(down_node) alice.remember_node(down_node)
blockchain_alice.network_middleware.node_is_down(down_node) alice.network_middleware.node_is_down(down_node)
# Here's the command we want to run. # Here's the command we want to run.
alice_grant_action = partial( alice_grant_action = partial(
blockchain_alice.grant, alice.grant,
blockchain_bob, bob,
label, label,
threshold=threshold, threshold=threshold,
shares=shares, shares=shares,
@ -38,7 +38,7 @@ def test_alice_can_grant_even_when_the_first_nodes_she_tries_are_down(
) )
# Go! # Go!
blockchain_alice.start_learning_loop() alice.start_learning_loop()
# Now we'll have a situation where Alice knows about all 10, # Now we'll have a situation where Alice knows about all 10,
# though only one is up. # though only one is up.
@ -47,18 +47,18 @@ def test_alice_can_grant_even_when_the_first_nodes_she_tries_are_down(
# Because she has successfully completed learning, but the nodes about which she learned are down, # Because she has successfully completed learning, but the nodes about which she learned are down,
# she'll get a different error. # she'll get a different error.
more_nodes = list(blockchain_ursulas)[1:10] more_nodes = list(ursulas)[1:10]
for node in more_nodes: for node in more_nodes:
blockchain_alice.network_middleware.node_is_down(node) alice.network_middleware.node_is_down(node)
for node in more_nodes: for node in more_nodes:
blockchain_alice.remember_node(node) alice.remember_node(node)
with pytest.raises(Policy.NotEnoughUrsulas): with pytest.raises(Policy.NotEnoughUrsulas):
alice_grant_action() alice_grant_action()
# Now let's let a few of them come up. # Now let's let a few of them come up.
for node in more_nodes[0:4]: for node in more_nodes[0:4]:
blockchain_alice.network_middleware.node_is_up(node) alice.network_middleware.node_is_up(node)
# Now the same exact action works. # Now the same exact action works.
# TODO: This action only succeeds here because we are forcing # TODO: This action only succeeds here because we are forcing
@ -73,15 +73,15 @@ def test_alice_can_grant_even_when_the_first_nodes_she_tries_are_down(
assert policy.shares == shares assert policy.shares == shares
def test_node_has_changed_cert(blockchain_alice, blockchain_ursulas): def test_node_has_changed_cert(alice, ursulas):
blockchain_alice.known_nodes.current_state._nodes = {} alice.known_nodes.current_state._nodes = {}
blockchain_alice.network_middleware = NodeIsDownMiddleware() alice.network_middleware = NodeIsDownMiddleware()
blockchain_alice.network_middleware.client.certs_are_broken = True alice.network_middleware.client.certs_are_broken = True
firstula = list(blockchain_ursulas)[0] firstula = list(ursulas)[0]
blockchain_alice.remember_node(firstula) alice.remember_node(firstula)
blockchain_alice.start_learning_loop(now=True) alice.start_learning_loop(now=True)
blockchain_alice.learn_from_teacher_node() alice.learn_from_teacher_node()
# Cool - we didn't crash because of SSLError. # Cool - we didn't crash because of SSLError.
# TODO: Assertions and such. # TODO: Assertions and such.

View File

@ -7,8 +7,8 @@ from twisted.internet.threads import deferToThread
@pt.inlineCallbacks @pt.inlineCallbacks
def test_one_node_stores_a_bunch_of_others(blockchain_ursulas, lonely_ursula_maker): def test_one_node_stores_a_bunch_of_others(ursulas, lonely_ursula_maker):
the_chosen_seednode = list(blockchain_ursulas)[2] # ...neo? the_chosen_seednode = list(ursulas)[2] # ...neo?
seed_node = the_chosen_seednode.seed_node_metadata() seed_node = the_chosen_seednode.seed_node_metadata()
newcomer = lonely_ursula_maker( newcomer = lonely_ursula_maker(

View File

@ -3,28 +3,22 @@ from nucypher_core import HRAC
from nucypher.characters.lawful import Ursula from nucypher.characters.lawful import Ursula
def test_alice_creates_policy_with_correct_hrac( def test_alice_creates_policy_with_correct_hrac(alice, bob, idle_policy):
blockchain_alice, blockchain_bob, idle_blockchain_policy
):
""" """
Alice creates a Policy. It has the proper HRAC, unique per her, Bob, and the label Alice creates a Policy. It has the proper HRAC, unique per her, Bob, and the label
""" """
# TODO: what are we actually testing here? # TODO: what are we actually testing here?
assert idle_blockchain_policy.hrac == HRAC( assert idle_policy.hrac == HRAC(
blockchain_alice.stamp.as_umbral_pubkey(), alice.stamp.as_umbral_pubkey(), bob.stamp.as_umbral_pubkey(), idle_policy.label
blockchain_bob.stamp.as_umbral_pubkey(),
idle_blockchain_policy.label,
) )
def test_alice_does_not_update_with_old_ursula_info( def test_alice_does_not_update_with_old_ursula_info(alice, ursulas):
blockchain_alice, blockchain_ursulas ursula = list(ursulas)[0]
):
ursula = list(blockchain_ursulas)[0]
old_metadata = bytes(ursula.metadata()) old_metadata = bytes(ursula.metadata())
# Alice has remembered Ursula. # Alice has remembered Ursula.
assert blockchain_alice.known_nodes[ursula.checksum_address] == ursula assert alice.known_nodes[ursula.checksum_address] == ursula
# But now, Ursula wants to sign and date her metadata again. This causes a new timestamp. # But now, Ursula wants to sign and date her metadata again. This causes a new timestamp.
ursula._metadata = None ursula._metadata = None
@ -36,12 +30,10 @@ def test_alice_does_not_update_with_old_ursula_info(
old_ursula = Ursula.from_metadata_bytes(old_metadata) old_ursula = Ursula.from_metadata_bytes(old_metadata)
# Once Alice learns about Ursula's updated info... # Once Alice learns about Ursula's updated info...
blockchain_alice.remember_node(ursula) alice.remember_node(ursula)
# ...she can't learn about old ursula anymore. # ...she can't learn about old ursula anymore.
blockchain_alice.remember_node(old_ursula) alice.remember_node(old_ursula)
new_metadata = bytes( new_metadata = bytes(alice.known_nodes[ursula.checksum_address].metadata())
blockchain_alice.known_nodes[ursula.checksum_address].metadata()
)
assert new_metadata != old_metadata assert new_metadata != old_metadata

View File

@ -5,12 +5,12 @@ from nucypher_core import MessageKit
from nucypher.characters.lawful import Enrico from nucypher.characters.lawful import Enrico
def test_message_kit_serialization_via_enrico(blockchain_alice): def test_message_kit_serialization_via_enrico(alice):
mock_label = b'this is a label' mock_label = b'this is a label'
# Enrico # Enrico
enrico = Enrico.from_alice(blockchain_alice, label=mock_label) enrico = Enrico.from_alice(alice, label=mock_label)
# Plaintext # Plaintext
message = 'this is a message' message = 'this is a message'

View File

@ -1,8 +1,8 @@
from nucypher.characters.lawful import Ursula from nucypher.characters.lawful import Ursula
def test_serialize_ursula(blockchain_ursulas): def test_serialize_ursula(ursulas):
ursula = blockchain_ursulas[5] ursula = ursulas[5]
ursula_as_bytes = bytes(ursula.metadata()) ursula_as_bytes = bytes(ursula.metadata())
ursula_object = Ursula.from_metadata_bytes(ursula_as_bytes) ursula_object = Ursula.from_metadata_bytes(ursula_as_bytes)
assert ursula == ursula_object assert ursula == ursula_object

View File

@ -60,7 +60,7 @@ def select_test_port() -> int:
return port return port
def make_decentralized_ursulas( def make_ursulas(
ursula_config: UrsulaConfiguration, ursula_config: UrsulaConfiguration,
staking_provider_addresses: Iterable[str], staking_provider_addresses: Iterable[str],
operator_addresses: Iterable[str], operator_addresses: Iterable[str],
@ -69,9 +69,7 @@ def make_decentralized_ursulas(
**ursula_overrides **ursula_overrides
) -> List[Ursula]: ) -> List[Ursula]:
providers_and_operators = list(zip(staking_provider_addresses, operator_addresses))[ providers_and_operators = list(zip(staking_provider_addresses, operator_addresses))[:quantity]
:quantity
]
ursulas = list() ursulas = list()
for staking_provider_address, operator_address in providers_and_operators: for staking_provider_address, operator_address in providers_and_operators:
@ -113,11 +111,13 @@ def make_ursula_for_staking_provider(staking_provider,
# Assign worker to this staking provider # Assign worker to this staking provider
staking_provider.bond_worker(operator_address=operator_address) staking_provider.bond_worker(operator_address=operator_address)
worker = make_decentralized_ursulas(ursula_config=ursula_config, worker = make_ursulas(
blockchain=blockchain, ursula_config=ursula_config,
staking_provider_addresses=[staking_provider.checksum_address], blockchain=blockchain,
operator_addresses=[operator_address], staking_provider_addresses=[staking_provider.checksum_address],
**ursula_overrides).pop() operator_addresses=[operator_address],
**ursula_overrides
).pop()
for ursula_to_learn_about in (ursulas_to_learn_about or []): for ursula_to_learn_about in (ursulas_to_learn_about or []):
worker.remember_node(ursula_to_learn_about) worker.remember_node(ursula_to_learn_about)