mirror of https://github.com/nucypher/nucypher.git
Removes "decentralized" and "blockchain" differentiation from "federated"
parent
18d3d6e0a5
commit
fda5c86db2
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
)
|
||||||
|
|
|
@ -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,
|
||||||
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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...
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue