nucypher/tests/fixtures.py

826 lines
29 KiB
Python
Raw Normal View History

"""
This file is part of nucypher.
nucypher is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
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
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
import datetime
import json
import os
import random
import tempfile
import maya
import pytest
2019-09-09 14:28:51 +00:00
from eth_utils import to_checksum_address
from sqlalchemy.engine import create_engine
from twisted.logger import Logger
from umbral import pre
from umbral.curvebn import CurveBN
from umbral.keys import UmbralPrivateKey
from umbral.signing import Signer
2019-06-04 15:34:02 +00:00
from web3 import Web3
from nucypher.blockchain.economics import StandardTokenEconomics
from nucypher.blockchain.eth.actors import Staker, StakeHolder
from nucypher.blockchain.eth.agents import NucypherTokenAgent
from nucypher.blockchain.eth.clients import NuCypherGethDevProcess
from nucypher.blockchain.eth.deployers import (NucypherTokenDeployer,
StakingEscrowDeployer,
PolicyManagerDeployer,
2019-10-17 11:03:29 +00:00
AdjudicatorDeployer, StakingInterfaceDeployer)
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.registry import InMemoryContractRegistry
from nucypher.blockchain.eth.sol.compile import SolidityCompiler
from nucypher.blockchain.eth.token import NU
from nucypher.characters.lawful import Enrico, Bob
from nucypher.config.characters import (
UrsulaConfiguration,
AliceConfiguration,
BobConfiguration,
StakeHolderConfiguration
)
from nucypher.config.node import CharacterConfiguration
from nucypher.crypto.powers import TransactingPower
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
from nucypher.policy.collections import IndisputableEvidence, WorkOrder
from nucypher.utilities.sandbox.blockchain import token_airdrop, TesterBlockchain
from nucypher.utilities.sandbox.constants import (
DEVELOPMENT_ETH_AIRDROP_AMOUNT,
DEVELOPMENT_TOKEN_AIRDROP_AMOUNT,
MIN_STAKE_FOR_TESTS,
BONUS_TOKENS_FOR_TESTS,
MOCK_POLICY_DEFAULT_M,
MOCK_URSULA_STARTING_PORT,
NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK,
TEMPORARY_DOMAIN,
TEST_PROVIDER_URI,
INSECURE_DEVELOPMENT_PASSWORD,
MOCK_REGISTRY_FILEPATH,
TEST_GAS_LIMIT,
INSECURE_DEPLOYMENT_SECRET_HASH,
)
from nucypher.utilities.sandbox.middleware import MockRestMiddleware
2019-02-16 18:57:44 +00:00
from nucypher.utilities.sandbox.policy import generate_random_label
from nucypher.utilities.sandbox.ursula import make_decentralized_ursulas, make_federated_ursulas
CharacterConfiguration.DEFAULT_DOMAIN = TEMPORARY_DOMAIN
2018-10-11 03:11:25 +00:00
test_logger = Logger("test-logger")
#
# Temporary
#
@pytest.fixture(scope="function")
def tempfile_path():
fd, path = tempfile.mkstemp()
yield path
os.close(fd)
os.remove(path)
@pytest.fixture(scope="module")
def temp_dir_path():
temp_dir = tempfile.TemporaryDirectory(prefix='nucypher-test-')
yield temp_dir.name
temp_dir.cleanup()
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
@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()
#
# Configuration
#
@pytest.fixture(scope="module")
def ursula_federated_test_config():
ursula_config = UrsulaConfiguration(dev_mode=True,
rest_port=MOCK_URSULA_STARTING_PORT,
start_learning_now=False,
abort_on_learning_error=True,
federated_only=True,
network_middleware=MockRestMiddleware(),
save_metadata=False,
reload_metadata=False,)
yield ursula_config
ursula_config.cleanup()
@pytest.fixture(scope="module")
def ursula_decentralized_test_config(test_registry):
ursula_config = UrsulaConfiguration(dev_mode=True,
provider_uri=TEST_PROVIDER_URI,
rest_port=MOCK_URSULA_STARTING_PORT,
start_learning_now=False,
abort_on_learning_error=True,
federated_only=False,
network_middleware=MockRestMiddleware(),
save_metadata=False,
reload_metadata=False,
registry=test_registry)
yield ursula_config
ursula_config.cleanup()
@pytest.fixture(scope="module")
def alice_federated_test_config(federated_ursulas):
config = AliceConfiguration(dev_mode=True,
network_middleware=MockRestMiddleware(),
known_nodes=federated_ursulas,
federated_only=True,
abort_on_learning_error=True,
save_metadata=False,
reload_metadata=False)
yield config
config.cleanup()
@pytest.fixture(scope="module")
def alice_blockchain_test_config(blockchain_ursulas, testerchain, test_registry):
config = AliceConfiguration(dev_mode=True,
provider_uri=TEST_PROVIDER_URI,
checksum_address=testerchain.alice_account,
network_middleware=MockRestMiddleware(),
known_nodes=blockchain_ursulas,
abort_on_learning_error=True,
save_metadata=False,
reload_metadata=False,
registry=test_registry)
yield config
config.cleanup()
@pytest.fixture(scope="module")
def bob_federated_test_config():
config = BobConfiguration(dev_mode=True,
network_middleware=MockRestMiddleware(),
start_learning_now=False,
abort_on_learning_error=True,
federated_only=True,
save_metadata=False,
reload_metadata=False)
yield config
config.cleanup()
@pytest.fixture(scope="module")
def bob_blockchain_test_config(blockchain_ursulas, testerchain, test_registry):
config = BobConfiguration(dev_mode=True,
provider_uri=TEST_PROVIDER_URI,
checksum_address=testerchain.bob_account,
network_middleware=MockRestMiddleware(),
known_nodes=blockchain_ursulas,
start_learning_now=False,
abort_on_learning_error=True,
federated_only=False,
save_metadata=False,
reload_metadata=False,
registry=test_registry)
yield config
config.cleanup()
2018-06-29 00:23:42 +00:00
#
# Policies
#
@pytest.fixture(scope="module")
def idle_federated_policy(federated_alice, federated_bob):
"""
Creates a Policy, in a manner typical of how Alice might do it, with a unique label
"""
m = MOCK_POLICY_DEFAULT_M
n = NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK
2019-02-16 18:57:44 +00:00
random_label = generate_random_label()
policy = federated_alice.create_policy(federated_bob,
label=random_label,
m=m,
n=n,
expiration=maya.now() + datetime.timedelta(days=5))
return policy
@pytest.fixture(scope="module")
def enacted_federated_policy(idle_federated_policy, federated_ursulas):
# Alice has a policy in mind and knows of enough qualifies Ursulas; she crafts an offer for them.
network_middleware = MockRestMiddleware()
idle_federated_policy.make_arrangements(network_middleware, handpicked_ursulas=federated_ursulas)
# REST call happens here, as does population of TreasureMap.
responses = idle_federated_policy.enact(network_middleware)
2018-06-29 00:23:42 +00:00
return idle_federated_policy
@pytest.fixture(scope="module")
def idle_blockchain_policy(blockchain_alice, blockchain_bob, token_economics):
2018-06-29 00:23:42 +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()
days = token_economics.minimum_locked_periods // 2
expiration = maya.now().add(days=days)
2019-03-05 00:53:11 +00:00
policy = blockchain_alice.create_policy(blockchain_bob,
label=random_label,
m=2, n=3,
value=3*days*100,
2019-03-05 00:53:11 +00:00
expiration=expiration)
2018-06-29 00:23:42 +00:00
return policy
@pytest.fixture(scope="module")
def enacted_blockchain_policy(idle_blockchain_policy, blockchain_ursulas):
# 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
# cannot set them again
# deposit = NON_PAYMENT(b"0000000")
# contract_end_datetime = maya.now() + datetime.timedelta(days=5)
2018-06-06 08:32:25 +00:00
network_middleware = MockRestMiddleware()
2019-09-28 23:57:54 +00:00
idle_blockchain_policy.make_arrangements(
network_middleware, handpicked_ursulas=list(blockchain_ursulas))
2018-06-29 00:23:42 +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
@pytest.fixture(scope="module")
def capsule_side_channel(enacted_federated_policy):
class _CapsuleSideChannel:
def __init__(self):
self.reset()
def __call__(self):
enrico = Enrico(policy_encrypting_key=enacted_federated_policy.public_key)
message = "Welcome to flippering number {}.".format(len(self.messages)).encode()
message_kit, _signature = enrico.encrypt_message(message)
self.messages.append((message_kit, enrico))
2019-09-29 05:19:53 +00:00
return message_kit, enrico
def reset(self):
self.messages = []
self()
return _CapsuleSideChannel()
@pytest.fixture(scope="module")
def capsule_side_channel_blockchain(enacted_blockchain_policy):
class _CapsuleSideChannel:
def __init__(self):
self.reset()
def __call__(self):
enrico = Enrico(policy_encrypting_key=enacted_blockchain_policy.public_key)
message = "Welcome to flippering number {}.".format(len(self.messages)).encode()
message_kit, _signature = enrico.encrypt_message(message)
self.messages.append((message_kit, enrico))
return message_kit, enrico
def reset(self):
self.messages = []
self()
return _CapsuleSideChannel()
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
#
# Alice, Bob, and Ursula
2018-06-29 00:23:42 +00:00
#
@pytest.fixture(scope="module")
def federated_alice(alice_federated_test_config):
_alice = alice_federated_test_config.produce()
return _alice
@pytest.fixture(scope="module")
def blockchain_alice(alice_blockchain_test_config, testerchain):
_alice = alice_blockchain_test_config.produce()
return _alice
@pytest.fixture(scope="module")
def federated_bob(bob_federated_test_config):
_bob = bob_federated_test_config.produce()
return _bob
2018-06-29 00:23:42 +00:00
@pytest.fixture(scope="module")
def blockchain_bob(bob_blockchain_test_config, testerchain):
_bob = bob_blockchain_test_config.produce()
return _bob
2018-06-29 00:23:42 +00:00
@pytest.fixture(scope="module")
def federated_ursulas(ursula_federated_test_config):
_ursulas = make_federated_ursulas(ursula_config=ursula_federated_test_config,
quantity=NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK)
yield _ursulas
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
#
@pytest.fixture(scope='session')
def token_economics():
2019-06-15 16:51:06 +00:00
economics = StandardTokenEconomics()
return economics
2019-04-25 13:13:46 +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."""
compiler = SolidityCompiler()
2018-06-29 00:23:42 +00:00
yield compiler
@pytest.fixture(scope='module')
def test_registry():
registry = InMemoryContractRegistry()
return registry
def _make_testerchain():
2018-04-13 00:24:55 +00:00
"""
https://github.com/ethereum/eth-tester # available-backends
2018-04-13 00:24:55 +00:00
"""
# Monkey patch to prevent gas adjustment
import eth
eth._utils.headers.GAS_LIMIT_MINIMUM = TEST_GAS_LIMIT
eth._utils.headers.GENESIS_GAS_LIMIT = TEST_GAS_LIMIT
eth.vm.forks.frontier.headers.GENESIS_GAS_LIMIT = TEST_GAS_LIMIT
2019-09-10 15:34:20 +00:00
# Monkey patch to prevent gas estimates
def _get_buffered_gas_estimate(web3, transaction, gas_buffer=100000):
return TEST_GAS_LIMIT
import web3
web3.eth.get_buffered_gas_estimate = _get_buffered_gas_estimate
2018-06-29 00:23:42 +00:00
# Create the blockchain
testerchain = TesterBlockchain(eth_airdrop=True, free_transactions=True)
BlockchainInterfaceFactory.register_interface(interface=testerchain)
# Mock TransactingPower Consumption (Deployer)
testerchain.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
account=testerchain.etherbase_account)
testerchain.transacting_power.activate()
return testerchain
@pytest.fixture(scope='session')
def _testerchain():
testerchain = _make_testerchain()
2018-06-29 00:23:42 +00:00
yield testerchain
@pytest.fixture(scope='module')
def testerchain(_testerchain):
testerchain = _testerchain
2019-09-09 14:28:51 +00:00
# Reset chain state
pyevm_backend = testerchain.provider.ethereum_tester.backend
2019-09-15 15:22:27 +00:00
snapshot = pyevm_backend.chain.get_canonical_block_by_number(0).hash
pyevm_backend.revert_to_snapshot(snapshot)
2019-09-09 14:28:51 +00:00
coinbase, *addresses = testerchain.client.accounts
for address in addresses:
balance = testerchain.client.get_balance(address)
spent = DEVELOPMENT_ETH_AIRDROP_AMOUNT - balance
if spent > 0:
tx = {'to': address, 'from': coinbase, 'value': spent}
txhash = testerchain.w3.eth.sendTransaction(tx)
_receipt = testerchain.wait_for_receipt(txhash)
eth_amount = Web3().fromWei(spent, 'ether')
testerchain.log.info("Airdropped {} ETH {} -> {}".format(eth_amount, tx['from'], tx['to']))
yield testerchain
def _make_agency(testerchain, test_registry):
"""
Launch the big three contracts on provided chain,
make agents for each and return them.
"""
# Mock TransactingPower Consumption (Deployer)
testerchain.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
account=testerchain.etherbase_account)
testerchain.transacting_power.activate()
2019-04-10 09:46:22 +00:00
origin = testerchain.etherbase_account
2018-06-29 00:23:42 +00:00
token_deployer = NucypherTokenDeployer(deployer_address=origin, registry=test_registry)
2018-06-29 00:23:42 +00:00
token_deployer.deploy()
staking_escrow_deployer = StakingEscrowDeployer(deployer_address=origin, registry=test_registry)
staking_escrow_deployer.deploy(secret_hash=INSECURE_DEPLOYMENT_SECRET_HASH)
policy_manager_deployer = PolicyManagerDeployer(deployer_address=origin, registry=test_registry)
policy_manager_deployer.deploy(secret_hash=INSECURE_DEPLOYMENT_SECRET_HASH)
2018-06-29 00:23:42 +00:00
adjudicator_deployer = AdjudicatorDeployer(deployer_address=origin, registry=test_registry)
adjudicator_deployer.deploy(secret_hash=INSECURE_DEPLOYMENT_SECRET_HASH)
2019-10-17 11:03:29 +00:00
staking_interface_deployer = StakingInterfaceDeployer(deployer_address=origin, registry=test_registry)
staking_interface_deployer.deploy(secret_hash=INSECURE_DEPLOYMENT_SECRET_HASH)
token_agent = token_deployer.make_agent() # 1 Token
2019-09-10 18:38:38 +00:00
staking_agent = staking_escrow_deployer.make_agent() # 2 Staking Escrow
policy_agent = policy_manager_deployer.make_agent() # 3 Policy Agent
_adjudicator_agent = adjudicator_deployer.make_agent() # 4 Adjudicator
# TODO: Get rid of returning these agents here.
# What's important is deploying and creating the first agent for each contract,
# and since agents are singletons, in tests it's only necessary to call the agent
# constructor again to receive the existing agent.
#
# For example:
# staking_agent = StakingEscrowAgent()
#
# This is more clear than how we currently obtain an agent instance in tests:
# _, staking_agent, _ = agency
#
# Other advantages is that it's closer to how agents should be use (i.e., there
# are no fixtures IRL) and it's more extensible (e.g., AdjudicatorAgent)
return token_agent, staking_agent, policy_agent
@pytest.fixture(scope='module')
def agency(testerchain, test_registry):
agents = _make_agency(testerchain=testerchain, test_registry=test_registry)
yield agents
@pytest.fixture(scope="module")
def stakers(testerchain, agency, token_economics, test_registry):
token_agent, _staking_agent, _policy_agent = agency
2019-04-10 09:46:22 +00:00
blockchain = token_agent.blockchain
# Mock Powerup consumption (Deployer)
blockchain.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
account=blockchain.etherbase_account)
blockchain.transacting_power.activate()
2019-04-10 09:46:22 +00:00
token_airdrop(origin=blockchain.etherbase_account,
addresses=blockchain.stakers_accounts,
token_agent=token_agent,
amount=DEVELOPMENT_TOKEN_AIRDROP_AMOUNT)
stakers = list()
for index, account in enumerate(blockchain.stakers_accounts):
staker = Staker(is_me=True, checksum_address=account, registry=test_registry)
# Mock TransactingPower consumption
staker.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD, account=account)
staker.transacting_power.activate()
amount = MIN_STAKE_FOR_TESTS + random.randrange(BONUS_TOKENS_FOR_TESTS)
# for a random lock duration
2019-06-21 13:49:06 +00:00
min_locktime, max_locktime = token_economics.minimum_locked_periods, token_economics.maximum_rewarded_periods
periods = random.randint(min_locktime, max_locktime)
staker.initialize_stake(amount=amount, lock_periods=periods)
# We assume that the staker knows in advance the account of her worker
worker_address = blockchain.ursula_account(index)
staker.set_worker(worker_address=worker_address)
stakers.append(staker)
# Stake starts next period (or else signature validation will fail)
blockchain.time_travel(periods=1)
yield stakers
@pytest.fixture(scope="module")
def blockchain_ursulas(testerchain, stakers, ursula_decentralized_test_config):
_ursulas = make_decentralized_ursulas(ursula_config=ursula_decentralized_test_config,
stakers_addresses=testerchain.stakers_accounts,
workers_addresses=testerchain.ursulas_accounts,
confirm_activity=True)
testerchain.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)
yield _ursulas
@pytest.fixture(scope="module")
def idle_staker(testerchain, agency):
token_agent, _staking_agent, _policy_agent = agency
idle_staker_account = testerchain.unassigned_accounts[-2]
# Mock Powerup consumption (Deployer)
testerchain.transacting_power = TransactingPower(account=testerchain.etherbase_account)
token_airdrop(origin=testerchain.etherbase_account,
addresses=[idle_staker_account],
token_agent=token_agent,
amount=DEVELOPMENT_TOKEN_AIRDROP_AMOUNT)
# Prepare idle staker
idle_staker = Staker(is_me=True,
checksum_address=idle_staker_account,
blockchain=testerchain)
yield idle_staker
@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):
value = policy_rate * token_economics.minimum_locked_periods
return value
@pytest.fixture(scope='module')
def funded_blockchain(testerchain, agency, token_economics, test_registry):
# Who are ya'?
deployer_address, *everyone_else, staking_participant = testerchain.client.accounts
# Free ETH!!!
testerchain.ether_airdrop(amount=DEVELOPMENT_ETH_AIRDROP_AMOUNT)
# Free Tokens!!!
token_airdrop(token_agent=NucypherTokenAgent(registry=test_registry),
origin=deployer_address,
addresses=everyone_else,
amount=token_economics.minimum_allowed_locked*5)
# HERE YOU GO
yield testerchain, deployer_address
#
# 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 = b''.join((bytes(capsule),
bytes(ursula_pubkey),
bytes(ursula.decentralized_identity_evidence),
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
@pytest.fixture(scope='session')
def instant_geth_dev_node():
geth = NuCypherGethDevProcess()
try:
yield geth
finally:
if geth.is_running:
geth.stop()
assert not geth.is_running
@pytest.fixture(scope='session')
def stakeholder_config_file_location():
path = os.path.join('/', 'tmp', 'nucypher-test-stakeholder.json')
if os.path.exists(path):
os.remove(path)
yield path
if os.path.exists(path):
os.remove(path)
@pytest.fixture(scope='module')
def software_stakeholder(testerchain, agency, stakeholder_config_file_location, test_registry):
token_agent, staking_agent, policy_agent = agency
# Setup
path = stakeholder_config_file_location
if os.path.exists(path):
os.remove(path)
# 0xaAa482c790b4301bE18D75A0D1B11B2ACBEF798B
stakeholder_private_key = '255f64a948eeb1595b8a2d1e76740f4683eca1c8f1433d13293db9b6e27676cc'
address = testerchain.provider.ethereum_tester.add_account(stakeholder_private_key,
password=INSECURE_DEVELOPMENT_PASSWORD)
testerchain.provider.ethereum_tester.unlock_account(address, password=INSECURE_DEVELOPMENT_PASSWORD)
tx = {'to': address,
'from': testerchain.etherbase_account,
'value': Web3.toWei('1', 'ether')}
txhash = testerchain.client.w3.eth.sendTransaction(tx)
_receipt = testerchain.wait_for_receipt(txhash)
# Mock TransactingPower consumption (Etherbase)
transacting_power = TransactingPower(account=testerchain.etherbase_account,
password=INSECURE_DEVELOPMENT_PASSWORD)
transacting_power.activate()
token_agent.transfer(amount=NU(200_000, 'NU').to_nunits(),
sender_address=testerchain.etherbase_account,
target_address=address)
# Create stakeholder from on-chain values given accounts over a web3 provider
stakeholder = StakeHolder(registry=test_registry, initial_address=address)
# Teardown
yield stakeholder
if os.path.exists(path):
os.remove(path)
@pytest.fixture(scope="module")
def stakeholder_configuration(testerchain, mock_registry_filepath):
config = StakeHolderConfiguration(provider_uri=testerchain.provider_uri,
registry_filepath=mock_registry_filepath)
return config
@pytest.fixture(scope='module')
def manual_staker(testerchain, agency):
token_agent, staking_agent, policy_agent = agency
# 0xaaa23A5c74aBA6ca5E7c09337d5317A7C4563075
staker_private_key = '13378db1c2af06933000504838afc2d52efa383206454deefb1836f8f4cd86f8'
address = testerchain.provider.ethereum_tester.add_account(staker_private_key,
password=INSECURE_DEVELOPMENT_PASSWORD)
tx = {'to': address,
'from': testerchain.etherbase_account,
'value': Web3.toWei('1', 'ether')}
txhash = testerchain.client.w3.eth.sendTransaction(tx)
_receipt = testerchain.wait_for_receipt(txhash)
token_agent.transfer(amount=NU(200_000, 'NU').to_nunits(),
sender_address=testerchain.etherbase_account,
target_address=address)
yield address
@pytest.fixture(scope='module')
def manual_worker(testerchain):
worker_private_key = os.urandom(32).hex()
address = testerchain.provider.ethereum_tester.add_account(worker_private_key,
password=INSECURE_DEVELOPMENT_PASSWORD)
tx = {'to': address,
'from': testerchain.etherbase_account,
'value': Web3.toWei('1', 'ether')}
txhash = testerchain.client.w3.eth.sendTransaction(tx)
_receipt = testerchain.wait_for_receipt(txhash)
yield address
#
# Test logging
#
@pytest.fixture(autouse=True, scope='function')
def log_in_and_out_of_test(request):
test_name = request.node.name
module_name = request.module.__name__
test_logger.info(f"Starting {module_name}.py::{test_name}")
yield
test_logger.info(f"Finalized {module_name}.py::{test_name}")
@pytest.fixture(scope="module")
def deploy_contract(testerchain, test_registry):
def wrapped(contract_name, *args, **kwargs):
return testerchain.deploy_contract(testerchain.etherbase_account,
test_registry,
contract_name,
*args,
**kwargs)
return wrapped
@pytest.fixture(scope='module')
def mock_registry_filepath(testerchain, agency, test_registry):
# Fake the source contract registry
with open(MOCK_REGISTRY_FILEPATH, 'w') as file:
file.write(json.dumps(test_registry.read()))
yield MOCK_REGISTRY_FILEPATH
if os.path.isfile(MOCK_REGISTRY_FILEPATH):
os.remove(MOCK_REGISTRY_FILEPATH)
@pytest.fixture(scope='module')
def get_random_checksum_address():
def _get_random_checksum_address():
canonical_address = os.urandom(20)
checksum_address = to_checksum_address(canonical_address)
return checksum_address
return _get_random_checksum_address