2018-11-04 19:23:11 +00:00
|
|
|
"""
|
|
|
|
This file is part of nucypher.
|
|
|
|
|
|
|
|
nucypher is free software: you can redistribute it and/or modify
|
2019-03-05 02:50:11 +00:00
|
|
|
it under the terms of the GNU Affero General Public License as published by
|
2018-11-04 19:23:11 +00:00
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
nucypher is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2019-03-05 02:50:11 +00:00
|
|
|
GNU Affero General Public License for more details.
|
2018-11-04 19:23:11 +00:00
|
|
|
|
2019-03-05 02:50:11 +00:00
|
|
|
You should have received a copy of the GNU Affero General Public License
|
2018-11-04 19:23:11 +00:00
|
|
|
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
"""
|
2018-11-22 18:31:04 +00:00
|
|
|
|
2019-04-17 23:51:08 +00:00
|
|
|
import datetime
|
2018-08-05 20:09:05 +00:00
|
|
|
import os
|
|
|
|
import tempfile
|
2018-11-22 18:31:04 +00:00
|
|
|
|
2018-06-23 20:48:06 +00:00
|
|
|
import maya
|
|
|
|
import pytest
|
2019-02-15 03:48:15 +00:00
|
|
|
from constant_sorrow.constants import NON_PAYMENT
|
2018-06-23 20:48:06 +00:00
|
|
|
from sqlalchemy.engine import create_engine
|
2019-04-29 11:24:31 +00:00
|
|
|
from web3 import Web3
|
|
|
|
|
2019-05-13 08:27:50 +00:00
|
|
|
from umbral import pre
|
|
|
|
from umbral.curvebn import CurveBN
|
|
|
|
from umbral.keys import UmbralPrivateKey
|
|
|
|
from umbral.signing import Signer
|
|
|
|
|
2019-04-25 13:13:46 +00:00
|
|
|
from nucypher.blockchain.economics import TokenEconomics, SlashingEconomics
|
2019-05-17 01:19:40 +00:00
|
|
|
from nucypher.blockchain.eth.agents import NucypherTokenAgent
|
2019-05-31 16:15:47 +00:00
|
|
|
from nucypher.blockchain.eth.clients import NuCypherGethDevProcess
|
2019-04-29 11:24:31 +00:00
|
|
|
from nucypher.blockchain.eth.deployers import (NucypherTokenDeployer,
|
|
|
|
MinerEscrowDeployer,
|
|
|
|
PolicyManagerDeployer,
|
2019-04-04 02:26:37 +00:00
|
|
|
DispatcherDeployer,
|
|
|
|
MiningAdjudicatorDeployer)
|
2018-08-20 02:44:50 +00:00
|
|
|
from nucypher.blockchain.eth.interfaces import BlockchainDeployerInterface
|
2018-11-22 18:31:04 +00:00
|
|
|
from nucypher.blockchain.eth.registry import InMemoryEthereumContractRegistry
|
2018-08-18 23:24:13 +00:00
|
|
|
from nucypher.blockchain.eth.sol.compile import SolidityCompiler
|
2019-04-29 11:24:31 +00:00
|
|
|
from nucypher.blockchain.eth.token import NU
|
2019-05-13 08:27:50 +00:00
|
|
|
from nucypher.characters.lawful import Enrico, Bob
|
2018-09-23 04:05:11 +00:00
|
|
|
from nucypher.config.characters import UrsulaConfiguration, AliceConfiguration, BobConfiguration
|
2018-10-11 03:11:25 +00:00
|
|
|
from nucypher.config.constants import BASE_DIR
|
2018-09-17 21:06:43 +00:00
|
|
|
from nucypher.config.node import NodeConfiguration
|
2019-05-13 08:27:50 +00:00
|
|
|
from nucypher.crypto.utils import canonical_address_from_umbral_key
|
2018-05-08 19:35:34 +00:00
|
|
|
from nucypher.keystore import keystore
|
|
|
|
from nucypher.keystore.db import Base
|
2019-05-13 08:27:50 +00:00
|
|
|
from nucypher.policy.models import IndisputableEvidence, WorkOrder
|
2019-03-04 22:10:12 +00:00
|
|
|
from nucypher.utilities.sandbox.blockchain import token_airdrop, TesterBlockchain
|
2019-04-29 11:24:31 +00:00
|
|
|
from nucypher.utilities.sandbox.constants import (DEVELOPMENT_ETH_AIRDROP_AMOUNT,
|
|
|
|
DEVELOPMENT_TOKEN_AIRDROP_AMOUNT,
|
|
|
|
MOCK_POLICY_DEFAULT_M,
|
|
|
|
MOCK_URSULA_STARTING_PORT,
|
|
|
|
NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK,
|
2019-05-15 18:20:07 +00:00
|
|
|
TEMPORARY_DOMAIN,
|
|
|
|
TEST_PROVIDER_URI
|
2019-04-29 11:24:31 +00:00
|
|
|
)
|
2018-09-13 19:32:38 +00:00
|
|
|
from nucypher.utilities.sandbox.middleware import MockRestMiddleware
|
2019-02-16 18:57:44 +00:00
|
|
|
from nucypher.utilities.sandbox.policy import generate_random_label
|
2019-04-29 11:24:31 +00:00
|
|
|
from nucypher.utilities.sandbox.ursula import (make_decentralized_ursulas,
|
|
|
|
make_federated_ursulas,
|
|
|
|
start_pytest_ursula_services)
|
|
|
|
|
2018-06-29 00:23:42 +00:00
|
|
|
|
2018-10-11 03:11:25 +00:00
|
|
|
TEST_CONTRACTS_DIR = os.path.join(BASE_DIR, 'tests', 'blockchain', 'eth', 'contracts', 'contracts')
|
2019-05-15 18:20:07 +00:00
|
|
|
NodeConfiguration.DEFAULT_DOMAIN = TEMPORARY_DOMAIN
|
2018-10-11 03:11:25 +00:00
|
|
|
|
2018-09-17 21:06:43 +00:00
|
|
|
|
|
|
|
#
|
|
|
|
# Temporary
|
|
|
|
#
|
2018-09-16 21:35:17 +00:00
|
|
|
|
2018-09-20 00:01:01 +00:00
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
def tempfile_path():
|
|
|
|
fd, path = tempfile.mkstemp()
|
|
|
|
yield path
|
|
|
|
os.close(fd)
|
|
|
|
os.remove(path)
|
|
|
|
|
|
|
|
|
2018-09-21 16:03:45 +00:00
|
|
|
@pytest.fixture(scope="module")
|
2018-09-19 22:25:54 +00:00
|
|
|
def temp_dir_path():
|
2018-09-20 00:01:01 +00:00
|
|
|
temp_dir = tempfile.TemporaryDirectory(prefix='nucypher-test-')
|
2018-09-19 22:25:54 +00:00
|
|
|
yield temp_dir.name
|
|
|
|
temp_dir.cleanup()
|
2018-06-29 00:23:42 +00:00
|
|
|
|
|
|
|
|
2018-09-21 16:03:45 +00:00
|
|
|
@pytest.fixture(scope="module")
|
2018-09-19 22:25:54 +00:00
|
|
|
def temp_config_root(temp_dir_path):
|
2018-09-17 18:54:24 +00:00
|
|
|
"""
|
|
|
|
User is responsible for closing the file given at the path.
|
|
|
|
"""
|
2018-11-22 18:31:04 +00:00
|
|
|
default_node_config = NodeConfiguration(dev_mode=True,
|
2018-09-26 21:42:33 +00:00
|
|
|
config_root=temp_dir_path,
|
2019-04-27 19:58:23 +00:00
|
|
|
download_registry=False)
|
2018-09-17 21:06:43 +00:00
|
|
|
yield default_node_config.config_root
|
2018-09-21 16:03:45 +00:00
|
|
|
default_node_config.cleanup()
|
2018-09-17 18:54:24 +00:00
|
|
|
|
|
|
|
|
2018-06-29 00:23:42 +00:00
|
|
|
@pytest.fixture(scope="module")
|
|
|
|
def test_keystore():
|
|
|
|
engine = create_engine('sqlite:///:memory:')
|
|
|
|
Base.metadata.create_all(engine)
|
|
|
|
test_keystore = keystore.KeyStore(engine)
|
|
|
|
yield test_keystore
|
|
|
|
|
|
|
|
|
2018-10-29 00:37:37 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
def certificates_tempdir():
|
|
|
|
custom_filepath = '/tmp/nucypher-test-certificates-'
|
|
|
|
cert_tmpdir = tempfile.TemporaryDirectory(prefix=custom_filepath)
|
|
|
|
yield cert_tmpdir.name
|
|
|
|
cert_tmpdir.cleanup()
|
|
|
|
|
|
|
|
|
2018-09-13 19:35:44 +00:00
|
|
|
#
|
|
|
|
# Configuration
|
|
|
|
#
|
|
|
|
|
2018-09-17 18:54:24 +00:00
|
|
|
@pytest.fixture(scope="module")
|
2018-09-20 19:52:21 +00:00
|
|
|
def ursula_federated_test_config():
|
2018-11-22 18:31:04 +00:00
|
|
|
ursula_config = UrsulaConfiguration(dev_mode=True,
|
2018-12-03 02:47:14 +00:00
|
|
|
rest_port=MOCK_URSULA_STARTING_PORT,
|
2018-09-17 21:06:43 +00:00
|
|
|
is_me=True,
|
2018-09-22 22:44:37 +00:00
|
|
|
start_learning_now=False,
|
2018-09-20 19:52:21 +00:00
|
|
|
abort_on_learning_error=True,
|
2018-10-02 15:33:53 +00:00
|
|
|
federated_only=True,
|
2018-09-26 21:42:33 +00:00
|
|
|
network_middleware=MockRestMiddleware(),
|
2018-10-08 18:22:28 +00:00
|
|
|
save_metadata=False,
|
2018-11-26 04:41:31 +00:00
|
|
|
reload_metadata=False)
|
2018-09-17 21:06:43 +00:00
|
|
|
yield ursula_config
|
2018-09-24 20:59:38 +00:00
|
|
|
ursula_config.cleanup()
|
2018-09-17 21:06:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
2019-04-30 10:07:36 +00:00
|
|
|
def ursula_decentralized_test_config():
|
2018-11-22 18:31:04 +00:00
|
|
|
ursula_config = UrsulaConfiguration(dev_mode=True,
|
2018-09-17 21:06:43 +00:00
|
|
|
is_me=True,
|
2019-04-30 10:07:36 +00:00
|
|
|
provider_uri=TEST_PROVIDER_URI,
|
2018-12-03 02:47:14 +00:00
|
|
|
rest_port=MOCK_URSULA_STARTING_PORT,
|
2018-09-22 22:44:37 +00:00
|
|
|
start_learning_now=False,
|
2018-09-20 19:52:21 +00:00
|
|
|
abort_on_learning_error=True,
|
2018-10-02 15:33:53 +00:00
|
|
|
federated_only=False,
|
2018-09-26 21:42:33 +00:00
|
|
|
network_middleware=MockRestMiddleware(),
|
2019-04-30 18:04:37 +00:00
|
|
|
download_registry=False,
|
2018-10-08 18:22:28 +00:00
|
|
|
save_metadata=False,
|
2018-11-26 04:41:31 +00:00
|
|
|
reload_metadata=False)
|
2018-09-13 19:35:44 +00:00
|
|
|
yield ursula_config
|
2018-09-24 20:59:38 +00:00
|
|
|
ursula_config.cleanup()
|
2018-09-13 19:35:44 +00:00
|
|
|
|
|
|
|
|
2018-09-17 21:06:43 +00:00
|
|
|
@pytest.fixture(scope="module")
|
2018-09-20 19:52:21 +00:00
|
|
|
def alice_federated_test_config(federated_ursulas):
|
2018-11-22 18:31:04 +00:00
|
|
|
config = AliceConfiguration(dev_mode=True,
|
2018-09-20 19:52:21 +00:00
|
|
|
is_me=True,
|
2018-09-17 21:06:43 +00:00
|
|
|
network_middleware=MockRestMiddleware(),
|
|
|
|
known_nodes=federated_ursulas,
|
|
|
|
federated_only=True,
|
2018-09-26 21:42:33 +00:00
|
|
|
abort_on_learning_error=True,
|
2018-10-08 18:22:28 +00:00
|
|
|
save_metadata=False,
|
2018-11-26 04:41:31 +00:00
|
|
|
reload_metadata=False)
|
2018-09-17 21:06:43 +00:00
|
|
|
yield config
|
2018-09-24 20:59:38 +00:00
|
|
|
config.cleanup()
|
2018-09-17 21:06:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
2019-04-30 10:07:36 +00:00
|
|
|
def alice_blockchain_test_config(blockchain_ursulas, testerchain):
|
2018-11-22 18:31:04 +00:00
|
|
|
config = AliceConfiguration(dev_mode=True,
|
2018-09-17 21:06:43 +00:00
|
|
|
is_me=True,
|
2019-04-30 10:07:36 +00:00
|
|
|
provider_uri=TEST_PROVIDER_URI,
|
|
|
|
checksum_public_address=testerchain.alice_account,
|
2018-09-17 21:06:43 +00:00
|
|
|
network_middleware=MockRestMiddleware(),
|
2019-05-31 18:35:39 +00:00
|
|
|
known_nodes=blockchain_ursulas[:-1], # TODO: 1035
|
2018-09-17 21:06:43 +00:00
|
|
|
abort_on_learning_error=True,
|
2019-04-30 18:04:37 +00:00
|
|
|
download_registry=False,
|
2018-10-08 18:22:28 +00:00
|
|
|
save_metadata=False,
|
2018-11-26 04:41:31 +00:00
|
|
|
reload_metadata=False)
|
2018-09-17 21:06:43 +00:00
|
|
|
yield config
|
2018-09-24 20:59:38 +00:00
|
|
|
config.cleanup()
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
|
|
def bob_federated_test_config():
|
2018-11-22 18:31:04 +00:00
|
|
|
config = BobConfiguration(dev_mode=True,
|
2018-09-24 20:59:38 +00:00
|
|
|
network_middleware=MockRestMiddleware(),
|
|
|
|
start_learning_now=False,
|
|
|
|
abort_on_learning_error=True,
|
2018-09-26 21:42:33 +00:00
|
|
|
federated_only=True,
|
2018-10-08 18:22:28 +00:00
|
|
|
save_metadata=False,
|
2018-11-26 04:41:31 +00:00
|
|
|
reload_metadata=False)
|
2018-09-24 20:59:38 +00:00
|
|
|
yield config
|
|
|
|
config.cleanup()
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
2019-04-30 10:07:36 +00:00
|
|
|
def bob_blockchain_test_config(blockchain_ursulas, testerchain):
|
2018-11-22 18:31:04 +00:00
|
|
|
config = BobConfiguration(dev_mode=True,
|
2019-04-30 10:07:36 +00:00
|
|
|
provider_uri=TEST_PROVIDER_URI,
|
|
|
|
checksum_public_address=testerchain.bob_account,
|
2018-09-24 20:59:38 +00:00
|
|
|
network_middleware=MockRestMiddleware(),
|
2019-05-31 18:35:39 +00:00
|
|
|
known_nodes=blockchain_ursulas[:-1], # TODO: #1035
|
2018-09-24 20:59:38 +00:00
|
|
|
start_learning_now=False,
|
|
|
|
abort_on_learning_error=True,
|
2018-09-26 21:42:33 +00:00
|
|
|
federated_only=False,
|
2019-04-30 18:04:37 +00:00
|
|
|
download_registry=False,
|
2018-10-08 18:22:28 +00:00
|
|
|
save_metadata=False,
|
2018-11-26 04:41:31 +00:00
|
|
|
reload_metadata=False)
|
2018-09-24 20:59:38 +00:00
|
|
|
yield config
|
|
|
|
config.cleanup()
|
2018-09-17 21:06:43 +00:00
|
|
|
|
2019-02-13 05:42:12 +00:00
|
|
|
|
2018-06-29 00:23:42 +00:00
|
|
|
#
|
|
|
|
# Policies
|
|
|
|
#
|
2017-11-22 04:19:31 +00:00
|
|
|
|
2017-12-08 04:41:04 +00:00
|
|
|
|
2017-12-15 05:21:09 +00:00
|
|
|
@pytest.fixture(scope="module")
|
2018-09-24 20:59:38 +00:00
|
|
|
def idle_federated_policy(federated_alice, federated_bob):
|
2018-06-30 03:25:36 +00:00
|
|
|
"""
|
2018-10-28 22:15:16 +00:00
|
|
|
Creates a Policy, in a manner typical of how Alice might do it, with a unique label
|
2018-06-30 03:25:36 +00:00
|
|
|
"""
|
2019-02-10 19:56:43 +00:00
|
|
|
m = MOCK_POLICY_DEFAULT_M
|
2018-11-22 18:31:04 +00:00
|
|
|
n = NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK
|
2019-02-16 18:57:44 +00:00
|
|
|
random_label = generate_random_label()
|
2019-03-04 22:54:27 +00:00
|
|
|
policy = federated_alice.create_policy(federated_bob,
|
|
|
|
label=random_label,
|
|
|
|
m=m,
|
|
|
|
n=n,
|
|
|
|
federated=True)
|
2018-06-30 03:25:36 +00:00
|
|
|
return policy
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
2018-09-13 19:35:44 +00:00
|
|
|
def enacted_federated_policy(idle_federated_policy, federated_ursulas):
|
2018-06-30 03:25:36 +00:00
|
|
|
# Alice has a policy in mind and knows of enough qualifies Ursulas; she crafts an offer for them.
|
2018-11-22 18:31:04 +00:00
|
|
|
deposit = NON_PAYMENT
|
2018-06-30 03:25:36 +00:00
|
|
|
contract_end_datetime = maya.now() + datetime.timedelta(days=5)
|
|
|
|
network_middleware = MockRestMiddleware()
|
|
|
|
|
2018-06-29 00:23:42 +00:00
|
|
|
idle_federated_policy.make_arrangements(network_middleware,
|
2019-03-04 22:10:12 +00:00
|
|
|
value=deposit,
|
2018-06-29 00:23:42 +00:00
|
|
|
expiration=contract_end_datetime,
|
2018-09-13 19:35:44 +00:00
|
|
|
handpicked_ursulas=federated_ursulas)
|
2018-09-17 18:54:24 +00:00
|
|
|
|
2019-02-13 05:42:12 +00:00
|
|
|
responses = idle_federated_policy.enact(
|
|
|
|
network_middleware) # REST call happens here, as does population of TreasureMap.
|
2018-06-30 03:25:36 +00:00
|
|
|
|
2018-06-29 00:23:42 +00:00
|
|
|
return idle_federated_policy
|
2018-06-30 03:25:36 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
2019-03-20 04:18:24 +00:00
|
|
|
def idle_blockchain_policy(blockchain_alice, blockchain_bob, token_economics):
|
2018-06-29 00:23:42 +00:00
|
|
|
"""
|
2018-10-28 22:15:16 +00:00
|
|
|
Creates a Policy, in a manner typical of how Alice might do it, with a unique label
|
2018-06-29 00:23:42 +00:00
|
|
|
"""
|
2019-02-16 18:57:44 +00:00
|
|
|
random_label = generate_random_label()
|
2019-03-20 04:18:24 +00:00
|
|
|
expiration = maya.now().add(days=token_economics.minimum_locked_periods//2)
|
2019-03-05 00:53:11 +00:00
|
|
|
policy = blockchain_alice.create_policy(blockchain_bob,
|
|
|
|
label=random_label,
|
|
|
|
m=2, n=3,
|
|
|
|
value=20*100,
|
|
|
|
expiration=expiration)
|
2018-06-29 00:23:42 +00:00
|
|
|
return policy
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
2018-09-13 19:35:44 +00:00
|
|
|
def enacted_blockchain_policy(idle_blockchain_policy, blockchain_ursulas):
|
2019-02-14 08:23:48 +00:00
|
|
|
# Alice has a policy in mind and knows of enough qualified Ursulas; she crafts an offer for them.
|
2018-11-22 18:31:04 +00:00
|
|
|
deposit = NON_PAYMENT(b"0000000")
|
2018-04-07 02:26:13 +00:00
|
|
|
contract_end_datetime = maya.now() + datetime.timedelta(days=5)
|
2018-06-06 08:32:25 +00:00
|
|
|
network_middleware = MockRestMiddleware()
|
|
|
|
|
2018-09-24 20:59:38 +00:00
|
|
|
idle_blockchain_policy.make_arrangements(network_middleware,
|
2019-03-04 22:10:12 +00:00
|
|
|
value=deposit,
|
2018-09-24 20:59:38 +00:00
|
|
|
expiration=contract_end_datetime,
|
2018-09-13 19:35:44 +00:00
|
|
|
ursulas=list(blockchain_ursulas))
|
2018-06-29 00:23:42 +00:00
|
|
|
|
2018-09-24 20:59:38 +00:00
|
|
|
idle_blockchain_policy.enact(network_middleware) # REST call happens here, as does population of TreasureMap.
|
2018-06-29 00:23:42 +00:00
|
|
|
return idle_blockchain_policy
|
2017-11-22 04:19:31 +00:00
|
|
|
|
|
|
|
|
2018-09-24 20:59:38 +00:00
|
|
|
@pytest.fixture(scope="module")
|
|
|
|
def capsule_side_channel(enacted_federated_policy):
|
2019-02-15 02:27:41 +00:00
|
|
|
enrico = Enrico(policy_encrypting_key=enacted_federated_policy.public_key)
|
2019-02-13 20:51:04 +00:00
|
|
|
message_kit, _signature = enrico.encrypt_message(b"Welcome to the flippering.")
|
|
|
|
return message_kit, enrico
|
2018-09-24 20:59:38 +00:00
|
|
|
|
|
|
|
|
2019-02-16 20:36:08 +00:00
|
|
|
@pytest.fixture(scope="module")
|
|
|
|
def random_policy_label():
|
|
|
|
yield generate_random_label()
|
|
|
|
|
|
|
|
|
2018-06-29 00:23:42 +00:00
|
|
|
#
|
2018-09-24 20:59:38 +00:00
|
|
|
# Alice, Bob, and Ursula
|
2018-06-29 00:23:42 +00:00
|
|
|
#
|
2017-12-08 04:41:04 +00:00
|
|
|
|
2017-12-15 05:21:09 +00:00
|
|
|
@pytest.fixture(scope="module")
|
2018-09-24 20:59:38 +00:00
|
|
|
def federated_alice(alice_federated_test_config):
|
|
|
|
_alice = alice_federated_test_config.produce()
|
|
|
|
return _alice
|
2018-09-17 18:54:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
2018-09-17 21:06:43 +00:00
|
|
|
def blockchain_alice(alice_blockchain_test_config):
|
2018-09-24 20:59:38 +00:00
|
|
|
_alice = alice_blockchain_test_config.produce()
|
|
|
|
return _alice
|
2017-11-22 04:19:31 +00:00
|
|
|
|
|
|
|
|
2017-12-15 05:21:09 +00:00
|
|
|
@pytest.fixture(scope="module")
|
2018-09-24 20:59:38 +00:00
|
|
|
def federated_bob(bob_federated_test_config):
|
|
|
|
_bob = bob_federated_test_config.produce()
|
2018-06-01 20:34:42 +00:00
|
|
|
return _bob
|
2017-11-22 04:19:31 +00:00
|
|
|
|
|
|
|
|
2018-06-29 00:23:42 +00:00
|
|
|
@pytest.fixture(scope="module")
|
2018-09-24 20:59:38 +00:00
|
|
|
def blockchain_bob(bob_blockchain_test_config):
|
|
|
|
_bob = bob_blockchain_test_config.produce()
|
|
|
|
return _bob
|
2018-06-29 00:23:42 +00:00
|
|
|
|
|
|
|
|
2018-06-23 03:27:15 +00:00
|
|
|
@pytest.fixture(scope="module")
|
2018-09-17 21:06:43 +00:00
|
|
|
def federated_ursulas(ursula_federated_test_config):
|
2018-09-24 20:59:38 +00:00
|
|
|
_ursulas = make_federated_ursulas(ursula_config=ursula_federated_test_config,
|
2018-11-22 18:31:04 +00:00
|
|
|
quantity=NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK)
|
2018-09-24 20:59:38 +00:00
|
|
|
yield _ursulas
|
2017-12-08 04:41:26 +00:00
|
|
|
|
2019-04-10 09:46:22 +00:00
|
|
|
|
2018-06-29 00:23:42 +00:00
|
|
|
#
|
2019-04-10 09:46:22 +00:00
|
|
|
# Blockchain
|
2018-06-29 00:23:42 +00:00
|
|
|
#
|
|
|
|
|
2019-03-20 03:38:29 +00:00
|
|
|
@pytest.fixture(scope='session')
|
|
|
|
def token_economics():
|
|
|
|
economics = TokenEconomics()
|
|
|
|
return economics
|
2018-09-24 20:59:38 +00:00
|
|
|
|
2019-04-25 13:13:46 +00:00
|
|
|
|
|
|
|
@pytest.fixture(scope='session')
|
|
|
|
def slashing_economics():
|
|
|
|
economics = SlashingEconomics()
|
|
|
|
return economics
|
|
|
|
|
2019-04-30 10:07:36 +00:00
|
|
|
|
2018-06-29 00:23:42 +00:00
|
|
|
@pytest.fixture(scope='session')
|
|
|
|
def solidity_compiler():
|
|
|
|
"""Doing this more than once per session will result in slower test run times."""
|
2018-09-12 14:19:41 +00:00
|
|
|
compiler = SolidityCompiler(test_contract_dir=TEST_CONTRACTS_DIR)
|
2018-06-29 00:23:42 +00:00
|
|
|
yield compiler
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
|
|
def testerchain(solidity_compiler):
|
2018-04-13 00:24:55 +00:00
|
|
|
"""
|
2018-06-29 00:23:42 +00:00
|
|
|
https: // github.com / ethereum / eth - tester # available-backends
|
2018-04-13 00:24:55 +00:00
|
|
|
"""
|
2018-10-17 16:33:20 +00:00
|
|
|
memory_registry = InMemoryEthereumContractRegistry()
|
2018-06-29 00:23:42 +00:00
|
|
|
|
|
|
|
# Use the the custom provider and registrar to init an interface
|
2018-08-18 23:24:13 +00:00
|
|
|
|
2018-08-29 14:51:00 +00:00
|
|
|
deployer_interface = BlockchainDeployerInterface(compiler=solidity_compiler, # freshly recompile if not None
|
2018-10-17 16:33:20 +00:00
|
|
|
registry=memory_registry,
|
2019-04-30 08:24:30 +00:00
|
|
|
provider_uri=TEST_PROVIDER_URI)
|
2018-06-29 00:23:42 +00:00
|
|
|
|
|
|
|
# Create the blockchain
|
2019-04-22 20:15:40 +00:00
|
|
|
testerchain = TesterBlockchain(interface=deployer_interface,
|
|
|
|
eth_airdrop=True,
|
|
|
|
free_transactions=True,
|
|
|
|
poa=True)
|
2018-09-13 19:32:38 +00:00
|
|
|
|
2019-03-20 03:38:29 +00:00
|
|
|
# Set the deployer address from a freshly created test account
|
|
|
|
deployer_interface.deployer_address = testerchain.etherbase_account
|
2018-06-29 00:23:42 +00:00
|
|
|
|
|
|
|
yield testerchain
|
2019-04-22 20:15:40 +00:00
|
|
|
deployer_interface.disconnect()
|
2018-06-29 00:23:42 +00:00
|
|
|
testerchain.sever_connection()
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
|
|
def three_agents(testerchain):
|
|
|
|
"""
|
|
|
|
Musketeers, if you will.
|
|
|
|
Launch the big three contracts on provided chain,
|
|
|
|
make agents for each and return them.
|
|
|
|
"""
|
|
|
|
|
|
|
|
"""Launch all Nucypher ethereum contracts"""
|
2019-04-10 09:46:22 +00:00
|
|
|
origin = testerchain.etherbase_account
|
2018-06-29 00:23:42 +00:00
|
|
|
|
|
|
|
token_deployer = NucypherTokenDeployer(blockchain=testerchain, deployer_address=origin)
|
2018-10-26 14:48:10 +00:00
|
|
|
|
2018-06-29 00:23:42 +00:00
|
|
|
token_deployer.deploy()
|
|
|
|
|
2019-02-13 20:19:44 +00:00
|
|
|
token_agent = token_deployer.make_agent() # 1: Token
|
2018-06-29 00:23:42 +00:00
|
|
|
|
2019-04-04 02:26:37 +00:00
|
|
|
miner_escrow_deployer = MinerEscrowDeployer(deployer_address=origin)
|
|
|
|
miner_escrow_deployer.deploy(secret_hash=os.urandom(DispatcherDeployer.DISPATCHER_SECRET_LENGTH))
|
|
|
|
miner_agent = miner_escrow_deployer.make_agent() # 2 Miner Escrow
|
2018-10-26 14:48:10 +00:00
|
|
|
|
2019-04-04 02:26:37 +00:00
|
|
|
policy_manager_deployer = PolicyManagerDeployer(deployer_address=origin)
|
|
|
|
policy_manager_deployer.deploy(secret_hash=os.urandom(DispatcherDeployer.DISPATCHER_SECRET_LENGTH))
|
2018-06-29 00:23:42 +00:00
|
|
|
|
2019-04-18 19:48:31 +00:00
|
|
|
miner_agent = miner_escrow_deployer.make_agent() # 2 Miner Escrow
|
|
|
|
|
2019-02-13 20:19:44 +00:00
|
|
|
policy_agent = policy_manager_deployer.make_agent() # 3 Policy Agent
|
2018-06-29 00:23:42 +00:00
|
|
|
|
2019-04-04 02:26:37 +00:00
|
|
|
adjudicator_deployer = MiningAdjudicatorDeployer(deployer_address=origin)
|
|
|
|
adjudicator_deployer.deploy(secret_hash=os.urandom(DispatcherDeployer.DISPATCHER_SECRET_LENGTH))
|
|
|
|
|
2018-06-29 00:23:42 +00:00
|
|
|
return token_agent, miner_agent, policy_agent
|
2019-03-04 22:10:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
|
|
def blockchain_ursulas(three_agents, ursula_decentralized_test_config):
|
2019-04-30 10:07:36 +00:00
|
|
|
token_agent, _miner_agent, _policy_agent = three_agents
|
2019-04-10 09:46:22 +00:00
|
|
|
blockchain = token_agent.blockchain
|
2019-03-04 22:10:12 +00:00
|
|
|
|
2019-04-10 09:46:22 +00:00
|
|
|
token_airdrop(origin=blockchain.etherbase_account,
|
|
|
|
addresses=blockchain.ursulas_accounts,
|
2019-03-04 22:10:12 +00:00
|
|
|
token_agent=token_agent,
|
|
|
|
amount=DEVELOPMENT_TOKEN_AIRDROP_AMOUNT)
|
|
|
|
|
|
|
|
# Leave out the last Ursula for manual stake testing
|
2019-04-10 09:46:22 +00:00
|
|
|
*all_but_the_last_ursula, the_last_ursula = blockchain.ursulas_accounts
|
2019-03-04 22:10:12 +00:00
|
|
|
|
|
|
|
_ursulas = make_decentralized_ursulas(ursula_config=ursula_decentralized_test_config,
|
|
|
|
ether_addresses=all_but_the_last_ursula,
|
|
|
|
stake=True)
|
|
|
|
|
2019-05-31 15:26:05 +00:00
|
|
|
# Stake starts next period (or else signature validation will fail)
|
|
|
|
blockchain.time_travel(periods=1)
|
|
|
|
|
|
|
|
# Bootstrap the network
|
|
|
|
for ursula_to_teach in _ursulas:
|
|
|
|
for ursula_to_learn_about in _ursulas:
|
|
|
|
ursula_to_teach.remember_node(ursula_to_learn_about)
|
|
|
|
|
2019-05-31 16:15:47 +00:00
|
|
|
# TODO: #1035 - Move non-staking Ursulas to a new fixture
|
2019-03-04 22:10:12 +00:00
|
|
|
# This one is not going to stake
|
|
|
|
_non_staking_ursula = make_decentralized_ursulas(ursula_config=ursula_decentralized_test_config,
|
|
|
|
ether_addresses=[the_last_ursula],
|
|
|
|
stake=False)
|
|
|
|
|
2019-05-31 16:15:47 +00:00
|
|
|
_ursulas.extend(_non_staking_ursula)
|
2019-03-04 22:10:12 +00:00
|
|
|
yield _ursulas
|
|
|
|
|
2019-04-29 11:24:31 +00:00
|
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
|
|
def stake_value(token_economics):
|
|
|
|
value = NU(token_economics.minimum_allowed_locked * 2, 'NuNit')
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
|
|
def policy_rate():
|
|
|
|
rate = Web3.toWei(21, 'gwei')
|
|
|
|
return rate
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
|
|
def policy_value(token_economics, policy_rate):
|
2019-04-30 10:07:36 +00:00
|
|
|
value = policy_rate * token_economics.minimum_locked_periods
|
2019-04-29 11:24:31 +00:00
|
|
|
return value
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
2019-04-30 08:24:30 +00:00
|
|
|
def funded_blockchain(testerchain, three_agents, token_economics):
|
2019-04-29 11:24:31 +00:00
|
|
|
|
|
|
|
# Who are ya'?
|
2019-04-30 10:07:36 +00:00
|
|
|
deployer_address, *everyone_else, staking_participant = testerchain.interface.w3.eth.accounts
|
2019-04-29 11:24:31 +00:00
|
|
|
|
|
|
|
# Free ETH!!!
|
2019-04-30 10:07:36 +00:00
|
|
|
testerchain.ether_airdrop(amount=DEVELOPMENT_ETH_AIRDROP_AMOUNT)
|
2019-04-29 11:24:31 +00:00
|
|
|
|
|
|
|
# Free Tokens!!!
|
2019-04-30 10:07:36 +00:00
|
|
|
token_airdrop(token_agent=NucypherTokenAgent(blockchain=testerchain),
|
2019-04-30 08:24:30 +00:00
|
|
|
origin=deployer_address,
|
2019-04-29 11:24:31 +00:00
|
|
|
addresses=everyone_else,
|
|
|
|
amount=token_economics.minimum_allowed_locked*5)
|
|
|
|
|
|
|
|
# HERE YOU GO
|
2019-04-30 10:07:36 +00:00
|
|
|
yield testerchain, deployer_address
|
2019-04-29 11:24:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
|
|
def staking_participant(funded_blockchain, blockchain_ursulas):
|
2019-05-31 22:07:26 +00:00
|
|
|
|
2019-04-29 11:24:31 +00:00
|
|
|
# Start up the local fleet
|
|
|
|
for teacher in blockchain_ursulas:
|
|
|
|
start_pytest_ursula_services(ursula=teacher)
|
|
|
|
|
|
|
|
teachers = list(blockchain_ursulas)
|
2019-05-31 22:07:26 +00:00
|
|
|
staking_participant = teachers[-1] # TODO: # 1035
|
2019-04-29 11:24:31 +00:00
|
|
|
return staking_participant
|
2019-05-13 08:27:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
# Re-Encryption
|
|
|
|
#
|
|
|
|
|
|
|
|
def _mock_ursula_reencrypts(ursula, corrupt_cfrag: bool = False):
|
|
|
|
delegating_privkey = UmbralPrivateKey.gen_key()
|
|
|
|
_symmetric_key, capsule = pre._encapsulate(delegating_privkey.get_pubkey())
|
|
|
|
signing_privkey = UmbralPrivateKey.gen_key()
|
|
|
|
signing_pubkey = signing_privkey.get_pubkey()
|
|
|
|
signer = Signer(signing_privkey)
|
|
|
|
priv_key_bob = UmbralPrivateKey.gen_key()
|
|
|
|
pub_key_bob = priv_key_bob.get_pubkey()
|
|
|
|
kfrags = pre.generate_kfrags(delegating_privkey=delegating_privkey,
|
|
|
|
signer=signer,
|
|
|
|
receiving_pubkey=pub_key_bob,
|
|
|
|
threshold=2,
|
|
|
|
N=4,
|
|
|
|
sign_delegating_key=False,
|
|
|
|
sign_receiving_key=False)
|
|
|
|
capsule.set_correctness_keys(delegating_privkey.get_pubkey(), pub_key_bob, signing_pubkey)
|
|
|
|
|
|
|
|
ursula_pubkey = ursula.stamp.as_umbral_pubkey()
|
|
|
|
|
|
|
|
alice_address = canonical_address_from_umbral_key(signing_pubkey)
|
|
|
|
blockhash = bytes(32)
|
|
|
|
|
|
|
|
specification = bytes(capsule) + bytes(ursula_pubkey) + alice_address + blockhash
|
|
|
|
|
|
|
|
bobs_signer = Signer(priv_key_bob)
|
|
|
|
task_signature = bytes(bobs_signer(specification))
|
|
|
|
|
|
|
|
metadata = bytes(ursula.stamp(task_signature))
|
|
|
|
|
|
|
|
cfrag = pre.reencrypt(kfrags[0], capsule, metadata=metadata)
|
|
|
|
|
|
|
|
if corrupt_cfrag:
|
|
|
|
cfrag.proof.bn_sig = CurveBN.gen_rand(capsule.params.curve)
|
|
|
|
|
|
|
|
cfrag_signature = bytes(ursula.stamp(bytes(cfrag)))
|
|
|
|
|
|
|
|
bob = Bob.from_public_keys(verifying_key=pub_key_bob)
|
|
|
|
task = WorkOrder.Task(capsule, task_signature, cfrag, cfrag_signature)
|
|
|
|
work_order = WorkOrder(bob, None, alice_address, [task], None, ursula, blockhash)
|
|
|
|
|
|
|
|
evidence = IndisputableEvidence(task, work_order)
|
|
|
|
return evidence
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='session')
|
|
|
|
def mock_ursula_reencrypts():
|
|
|
|
return _mock_ursula_reencrypts
|
2019-05-31 16:15:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='session')
|
|
|
|
def geth_dev_node():
|
|
|
|
geth = NuCypherGethDevProcess()
|
|
|
|
try:
|
|
|
|
yield geth
|
|
|
|
finally:
|
|
|
|
if geth.is_running:
|
|
|
|
geth.stop()
|
|
|
|
assert not geth.is_running
|