mirror of https://github.com/nucypher/nucypher.git
Merge pull request #2560 from KPrasch/wake-up
Alternate finnegans wake demo for Lynx testnet + API Refinementspull/2569/head
commit
fcccf7789b
|
@ -31,6 +31,10 @@ without revealing data keys to intermediary entities.
|
|||
+------+-----------+----------------------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
There are two version of the example, one federated example using a local federated network
|
||||
and another example using the nucypher application development tesnet on Goerli: "Lynx".
|
||||
|
||||
|
||||
Install NuCypher
|
||||
----------------
|
||||
|
||||
|
@ -45,32 +49,34 @@ Acquire the ``nucypher`` application code and install the dependencies:
|
|||
(nucypher-venv)$ cd nucypher
|
||||
(nucypher-venv)$ pip install -e .
|
||||
|
||||
Federated Demo
|
||||
--------------
|
||||
|
||||
Run a fleet of federated Ursulas
|
||||
--------------------------------
|
||||
Run the local fleet of federated Ursulas in a separate terminal.
|
||||
This provides a network of 12 federated Ursulas.
|
||||
First run the local federated network:
|
||||
|
||||
.. code::
|
||||
|
||||
(nucypher)$ python examples/run_demo_ursula_fleet.py
|
||||
python ../run_demo_ursula_fleet.py
|
||||
|
||||
Download the Book Text
|
||||
----------------------
|
||||
For your convenience we have provided a bash script to acquire the "Finnegan's Wake" text. However,
|
||||
feel free to use any text of your choice, as long you you edit the demo code accordingly.
|
||||
|
||||
To run the script from the ``examples/finnegans_wake_demo`` directory:
|
||||
Then run the demo:
|
||||
|
||||
.. code::
|
||||
|
||||
(nucypher)$ ./download_finnegans_wake.sh
|
||||
python finnegans-wake-demo-federated.py
|
||||
|
||||
Run the Demo
|
||||
---------------
|
||||
Testnet Demo
|
||||
------------
|
||||
|
||||
After acquiring a text file to re-encrypt, execute the demo from the ``examples/finnegans_wake_demo`` by running:
|
||||
First, configure the demo. Be sure tat alice's address has some Goerli ETH.
|
||||
|
||||
.. code::
|
||||
|
||||
(nucypher)$ python finnegans-wake-demo.py
|
||||
export DEMO_PROVIDER_URI=<GOERLI RPC ENDPOINT>
|
||||
export DEMO_ALICE_ETH_ADDRESS=<ETH ADDRESS>
|
||||
export DEMO_SIGNER_URI=keystore://<PATH TO KEYSTORE>
|
||||
|
||||
Then run the demo:
|
||||
|
||||
.. code::
|
||||
|
||||
python finnegans-wake-demo-testnet.py
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Ursula exchange example over live network
|
||||
# Finnegan's Wake Demo
|
||||
|
||||
This illustrates Alice sharing data with Bob over the NuCypher network using proxy re-encryption,
|
||||
without revealing private keys to intermediary entities.
|
||||
|
@ -11,14 +11,25 @@ without revealing private keys to intermediary entities.
|
|||
5. Bob receives and reconstructs the Enrico from Policy public key and Enrico public key
|
||||
6. Bob retrieves the original message from Enrico and MessageKit
|
||||
|
||||
There are two version of the example, one federated example using a local network
|
||||
and another example using the nucypher application development tesnet: Lynx.
|
||||
|
||||
### Run a fleet of federated Ursulas
|
||||
### Federated Demo
|
||||
|
||||
First run the local federated network:
|
||||
`python ../run_demo_ursula_fleet.py`
|
||||
|
||||
Then run the demo:
|
||||
`python finnegans-wake-demo-federated.py`
|
||||
|
||||
### Download the Book!
|
||||
`./download_finnegans_wake.sh`
|
||||
### Testnet Demo
|
||||
|
||||
First, configure the demo. Be sure tat alice's address has some Goerli ETH.
|
||||
```bash
|
||||
export DEMO_PROVIDER_URI=<GOERLI RPC ENDPOINT>
|
||||
export DEMO_ALICE_ETH_ADDRESS=<ETH ADDRESS>
|
||||
export DEMO_SIGNER_URI=keystore://<PATH TO KEYSTORE>
|
||||
```
|
||||
|
||||
### Run
|
||||
`python finnegans-wake-demo.py`
|
||||
Then run the demo:
|
||||
`python finnegans-wake-demo-testnet.py`
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
echo "Downloading Finnegan's Wake Text..."
|
||||
wget "https://github.com/nucypher/nucypher/files/1765576/finnegans-wake.txt" -O ./finnegans-wake.txt
|
||||
echo "Successfully downloaded. To run the demo execute 'python finnegans-wake-demo.py'"
|
|
@ -15,40 +15,30 @@
|
|||
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import datetime
|
||||
import maya
|
||||
from umbral.keys import UmbralPublicKey
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from nucypher.characters.lawful import Alice, Bob, Ursula
|
||||
from nucypher.characters.lawful import Enrico as Enrico
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
from nucypher.network.middleware import RestMiddleware
|
||||
from nucypher.crypto.powers import SigningPower, DecryptingPower
|
||||
from nucypher.utilities.logging import GlobalLoggerSettings
|
||||
|
||||
|
||||
######################
|
||||
# Boring setup stuff #
|
||||
######################
|
||||
|
||||
# Execute the download script (download_finnegans_wake.sh) to retrieve the book
|
||||
BOOK_PATH = os.path.join('.', 'finnegans-wake.txt')
|
||||
|
||||
# Change this value to to perform more or less total re-encryptions
|
||||
# in order to avoid processing the entire book's text. (it's long)
|
||||
NUMBER_OF_LINES_TO_REENCRYPT = 25
|
||||
BOOK_PATH = Path(os.getenv('FINNEGANS_WAKE_PATH') or 'finnegans-wake-excerpt.txt')
|
||||
|
||||
# Twisted Logger
|
||||
GlobalLoggerSettings.set_log_level(log_level_name='debug')
|
||||
GlobalLoggerSettings.start_console_logging()
|
||||
|
||||
|
||||
#######################################
|
||||
# Finnegan's Wake on NuCypher Testnet #
|
||||
# (will fail with bad connection) #####
|
||||
#######################################
|
||||
|
||||
# if your ursulas are NOT running on your current host,
|
||||
# run like this: python finnegans-wake-demo.py 172.28.1.3:11500
|
||||
# otherwise the default will be fine.
|
||||
|
@ -61,55 +51,60 @@ except IndexError:
|
|||
##############################################
|
||||
# Ursula, the Untrusted Re-Encryption Proxy #
|
||||
##############################################
|
||||
ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URI,
|
||||
federated_only=True,
|
||||
minimum_stake=0)
|
||||
ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URI, federated_only=True)
|
||||
|
||||
# Here are our Policy details.
|
||||
policy_end_datetime = maya.now() + datetime.timedelta(days=5)
|
||||
policy_end_datetime = maya.now() + datetime.timedelta(days=1)
|
||||
m, n = 2, 3
|
||||
label = b"secret/files/and/stuff"
|
||||
|
||||
|
||||
#####################
|
||||
# Bob the BUIDLer ##
|
||||
#####################
|
||||
|
||||
# First there was Bob.
|
||||
bob = Bob(federated_only=True, domain=TEMPORARY_DOMAIN, known_nodes=[ursula])
|
||||
|
||||
# Bob gives his public keys to alice.
|
||||
verifying_key = bob.public_keys(SigningPower)
|
||||
encrypting_key = bob.public_keys(DecryptingPower)
|
||||
|
||||
######################################
|
||||
# Alice, the Authority of the Policy #
|
||||
######################################
|
||||
|
||||
ALICE = Alice(network_middleware=RestMiddleware(),
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
known_nodes=[ursula],
|
||||
learn_on_same_thread=True,
|
||||
federated_only=True)
|
||||
alice = Alice(federated_only=True, domain=TEMPORARY_DOMAIN, known_nodes=[ursula])
|
||||
|
||||
|
||||
# Start node discovery and wait until 8 nodes are known in case
|
||||
# the fleet isn't fully spun up yet, as sometimes happens on CI.
|
||||
alice.start_learning_loop(now=True)
|
||||
alice.block_until_number_of_known_nodes_is(8, timeout=30, learn_on_this_thread=True)
|
||||
|
||||
# Alice can get the public key even before creating the policy.
|
||||
# From this moment on, any Data Source that knows the public key
|
||||
# can encrypt data originally intended for Alice, but that can be shared with
|
||||
# any Bob that Alice grants access.
|
||||
policy_pubkey = ALICE.get_policy_encrypting_key_from_label(label)
|
||||
policy_public_key = alice.get_policy_encrypting_key_from_label(label)
|
||||
|
||||
BOB = Bob(known_nodes=[ursula],
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
network_middleware=RestMiddleware(),
|
||||
federated_only=True,
|
||||
start_learning_now=True,
|
||||
learn_on_same_thread=True)
|
||||
# Alice grant access to Bob. She already knows Bob's public keys from a side-channel.
|
||||
remote_bob = Bob.from_public_keys(encrypting_key=encrypting_key, verifying_key=verifying_key)
|
||||
policy = alice.grant(remote_bob, label, m=m, n=n, expiration=policy_end_datetime)
|
||||
|
||||
ALICE.start_learning_loop(now=True)
|
||||
ALICE.block_until_number_of_known_nodes_is(8, timeout=30, learn_on_this_thread=True) # In case the fleet isn't fully spun up yet, as sometimes happens on CI.
|
||||
|
||||
policy = ALICE.grant(BOB,
|
||||
label,
|
||||
m=m, n=n,
|
||||
expiration=policy_end_datetime)
|
||||
|
||||
assert policy.public_key == policy_pubkey
|
||||
assert policy.public_key == policy_public_key
|
||||
policy.treasure_map_publisher.block_until_complete()
|
||||
|
||||
# Alice puts her public key somewhere for Bob to find later...
|
||||
alices_pubkey_bytes_saved_for_posterity = bytes(ALICE.stamp)
|
||||
alice_verifying_key = bytes(alice.stamp)
|
||||
|
||||
# ...and then disappears from the internet.
|
||||
ALICE.disenchant()
|
||||
del ALICE
|
||||
#
|
||||
# Note that local characters (alice and bob), as opposed to objects representing
|
||||
# remote characters constructed from public data (remote_alice and remote_bob)
|
||||
# run a learning loop in a background thread and need to be stopped explicitly.
|
||||
alice.disenchant()
|
||||
del alice
|
||||
|
||||
#####################
|
||||
# some time passes. #
|
||||
|
@ -123,16 +118,16 @@ del ALICE
|
|||
# Bob the BUIDLer ##
|
||||
#####################
|
||||
|
||||
BOB.join_policy(label, alices_pubkey_bytes_saved_for_posterity)
|
||||
bob.join_policy(label, alice_verifying_key)
|
||||
|
||||
# Now that Bob has joined the Policy, let's show how Enrico the Encryptor
|
||||
# can share data with the members of this Policy and then how Bob retrieves it.
|
||||
# In order to avoid re-encrypting the entire book in this demo, we only read some lines.
|
||||
with open(BOOK_PATH, 'rb') as file:
|
||||
finnegans_wake = file.readlines()[:NUMBER_OF_LINES_TO_REENCRYPT]
|
||||
finnegans_wake = file.readlines()
|
||||
|
||||
print()
|
||||
print("**************James Joyce's Finnegan's Wake**************")
|
||||
print("**************James Joyce's Finnegan's Wake (Excerpt)**************")
|
||||
print()
|
||||
print("---------------------------------------------------------")
|
||||
|
||||
|
@ -141,7 +136,8 @@ for counter, plaintext in enumerate(finnegans_wake):
|
|||
#########################
|
||||
# Enrico, the Encryptor #
|
||||
#########################
|
||||
enrico = Enrico(policy_encrypting_key=policy_pubkey)
|
||||
|
||||
enrico = Enrico(policy_encrypting_key=policy_public_key)
|
||||
|
||||
# In this case, the plaintext is a
|
||||
# single passage from James Joyce's Finnegan's Wake.
|
||||
|
@ -155,20 +151,14 @@ for counter, plaintext in enumerate(finnegans_wake):
|
|||
# Back to Bob #
|
||||
###############
|
||||
|
||||
enrico_as_understood_by_bob = Enrico.from_public_keys(
|
||||
verifying_key=data_source_public_key,
|
||||
policy_encrypting_key=policy_pubkey
|
||||
)
|
||||
|
||||
# Now Bob can retrieve the original message.
|
||||
alice_pubkey_restored_from_ancient_scroll = UmbralPublicKey.from_bytes(alices_pubkey_bytes_saved_for_posterity)
|
||||
delivered_cleartexts = BOB.retrieve(single_passage_ciphertext,
|
||||
enrico=enrico_as_understood_by_bob,
|
||||
alice_verifying_key=alice_pubkey_restored_from_ancient_scroll,
|
||||
delivered_cleartexts = bob.retrieve(single_passage_ciphertext,
|
||||
policy_encrypting_key=policy_public_key,
|
||||
alice_verifying_key=alice_verifying_key,
|
||||
label=label)
|
||||
|
||||
# We show that indeed this is the passage originally encrypted by Enrico.
|
||||
assert plaintext == delivered_cleartexts[0]
|
||||
print("Retrieved: {}".format(delivered_cleartexts[0]))
|
||||
|
||||
BOB.disenchant()
|
||||
bob.disenchant()
|
|
@ -0,0 +1,164 @@
|
|||
"""
|
||||
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/>.
|
||||
"""
|
||||
|
||||
|
||||
from getpass import getpass
|
||||
|
||||
import datetime
|
||||
import maya
|
||||
import os
|
||||
from pathlib import Path
|
||||
from web3.main import Web3
|
||||
|
||||
from nucypher.blockchain.eth.signers.base import Signer
|
||||
from nucypher.characters.lawful import Alice, Bob, Ursula
|
||||
from nucypher.characters.lawful import Enrico as Enrico
|
||||
from nucypher.crypto.powers import SigningPower, DecryptingPower
|
||||
from nucypher.utilities.ethereum import connect_web3_provider
|
||||
from nucypher.utilities.logging import GlobalLoggerSettings
|
||||
|
||||
|
||||
######################
|
||||
# Boring setup stuff #
|
||||
######################
|
||||
|
||||
GlobalLoggerSettings.set_log_level(log_level_name='debug')
|
||||
GlobalLoggerSettings.start_console_logging()
|
||||
|
||||
BOOK_PATH = Path('finnegans-wake-excerpt.txt')
|
||||
|
||||
try:
|
||||
|
||||
# Replace with ethereum RPC endpoint
|
||||
PROVIDER_URI = os.environ['DEMO_PROVIDER_URI']
|
||||
|
||||
# Replace with wallet filepath.
|
||||
WALLET_FILEPATH = os.environ['DEMO_WALLET_FILEPATH']
|
||||
SIGNER_URI = f'keystore://{WALLET_FILEPATH}'
|
||||
|
||||
# Replace with alice's ethereum address
|
||||
ALICE_ADDRESS = os.environ['DEMO_ALICE_ADDRESS']
|
||||
|
||||
except KeyError:
|
||||
raise RuntimeError('Missing environment variables to run demo.')
|
||||
|
||||
|
||||
####################
|
||||
# NuCypher Network #
|
||||
####################
|
||||
|
||||
TESTNET = 'lynx'
|
||||
|
||||
#####################
|
||||
# Bob the BUIDLer ##
|
||||
#####################
|
||||
|
||||
# Then, there was bob. Bob learns about the
|
||||
# rest of the network from the seednode.
|
||||
bob = Bob(domain=TESTNET)
|
||||
|
||||
# Bob puts his public keys somewhere alice can find them.
|
||||
verifying_key = bob.public_keys(SigningPower)
|
||||
encrypting_key = bob.public_keys(DecryptingPower)
|
||||
|
||||
######################################
|
||||
# Alice, the Authority of the Policy #
|
||||
######################################
|
||||
|
||||
# Connect to the ethereum provider.
|
||||
connect_web3_provider(provider_uri=PROVIDER_URI)
|
||||
|
||||
# Setup and unlock alice's ethereum wallet.
|
||||
# WARNING: Never give your mainnet password or mnemonic phrase to anyone.
|
||||
# Do not use mainnet keys, create a dedicated software wallet to use for this demo.
|
||||
wallet = Signer.from_signer_uri(SIGNER_URI)
|
||||
password = os.environ.get('DEMO_ALICE_PASSWORD') or getpass(f"Enter password to unlock {ALICE_ADDRESS[:8]}: ")
|
||||
wallet.unlock_account(account=ALICE_ADDRESS, password=password)
|
||||
|
||||
# This is Alice.
|
||||
alice = Alice(checksum_address=ALICE_ADDRESS, signer=wallet, domain=TESTNET)
|
||||
|
||||
# Alice puts her public key somewhere for Bob to find later...
|
||||
alice_verifying_key = bytes(alice.stamp)
|
||||
|
||||
# Alice can get the policy's public key even before creating the policy.
|
||||
label = b"secret/files/42"
|
||||
policy_public_key = alice.get_policy_encrypting_key_from_label(label)
|
||||
|
||||
# From this moment on, anyone that knows the public key
|
||||
# can encrypt data originally intended for Alice, but that
|
||||
# can be shared with any Bob that Alice grants access.
|
||||
|
||||
# Alice already knows Bob's public keys from a side-channel.
|
||||
remote_bob = Bob.from_public_keys(encrypting_key=encrypting_key, verifying_key=verifying_key)
|
||||
|
||||
# These are the policy details for bob.
|
||||
# In this example bob will be granted access for 1 day,
|
||||
# trusting 2 of 3 nodes paying each of them 50 gwei per period.
|
||||
expiration = maya.now() + datetime.timedelta(days=1)
|
||||
rate = Web3.toWei(50, 'gwei')
|
||||
m, n = 2, 3
|
||||
|
||||
# Alice grants access to Bob...
|
||||
alice.grant(remote_bob, label, m=m, n=n, rate=rate, expiration=expiration)
|
||||
|
||||
# ...and then disappears from the internet.
|
||||
#
|
||||
# Note that local characters (alice and bob), as opposed to objects representing
|
||||
# remote characters constructed from public data (remote_alice and remote_bob)
|
||||
# run node discovery in a background thread and must be stopped explicitly.
|
||||
alice.disenchant()
|
||||
del alice
|
||||
|
||||
#########################
|
||||
# Enrico, the Encryptor #
|
||||
#########################
|
||||
|
||||
# Now that Bob has access to the policy, let's show how Enrico the Encryptor
|
||||
# can share data with the members of this Policy and then how Bob retrieves it.
|
||||
with open(BOOK_PATH, 'rb') as file:
|
||||
finnegans_wake = file.readlines()
|
||||
|
||||
print("\n**************James Joyce's Finnegan's Wake (Excerpt)**************\n")
|
||||
|
||||
for counter, plaintext in enumerate(finnegans_wake):
|
||||
|
||||
# Enrico knows the policy's public key from a side-channel.
|
||||
enrico = Enrico(policy_encrypting_key=policy_public_key)
|
||||
|
||||
# In this case, the plaintext is a single passage from James Joyce's Finnegan's Wake.
|
||||
# The matter of whether encryption makes the passage more or less readable
|
||||
# is left to the reader to determine. Many data sources (Enricos) can
|
||||
# encrypt fot the policy's public key.
|
||||
ciphertext, _signature = enrico.encrypt_message(plaintext)
|
||||
enrico_public_key = bytes(enrico.stamp)
|
||||
del enrico
|
||||
|
||||
###############
|
||||
# Back to Bob #
|
||||
###############
|
||||
|
||||
# Now Bob can retrieve the original message by requesting re-encryption from nodes.
|
||||
cleartexts = bob.retrieve(ciphertext,
|
||||
label=label,
|
||||
policy_encrypting_key=policy_public_key,
|
||||
alice_verifying_key=alice_verifying_key)
|
||||
|
||||
# We show that indeed this is the passage originally encrypted by Enrico.
|
||||
assert plaintext == cleartexts[0]
|
||||
|
||||
bob.disenchant()
|
|
@ -0,0 +1,22 @@
|
|||
Poof! There's puff for ye, begor, and planxty of it, all abound
|
||||
me breadth! Glor galore and glory be! As broad as its lung and
|
||||
as long as a line ! The valiantine vaux of Venerable Val Vous-
|
||||
dem. If my jaws must brass away like the due drops on my lay.
|
||||
And the topnoted delivery you'd expected be me invoice! Theo
|
||||
Dunnohoo's warning from Daddy O'Dowd. Whoo.^ What I'm
|
||||
wondering to myselfwhose for there's a strong tendency, to put
|
||||
it mildly, by making me the medium. I feel spirts of itchery out-
|
||||
ching out from all over me and only for the sludgehummer's
|
||||
force in my hand to hold them the darkens alone knows what' 11
|
||||
who'll be saying of next. However. Now, before my upperotic
|
||||
rogister, something nice. Now.^ Dear Sister, in perfect leave again I
|
||||
say take a brokerly advice and keep it to yourself that we, Jaun, first
|
||||
of our name here now make all receptacles of, free of price. Easy,
|
||||
my dear, if they tingle you either say nothing or nod. No cheeka-
|
||||
cheek with chipperchapper, you and your last mashboy and the
|
||||
padre in the pulpbox enumerating you his nostrums. Be vacillant
|
||||
over those vigilant who would leave you to belave black on white.
|
||||
Close in for psychical hijiniks as well but fight shy of mugpunters.
|
||||
I'd burn the books that grieve you and light an allassundrian bom-
|
||||
pyre that would suffragate Tome Plyfire or Zolfanerole. Perousse
|
||||
instate your Weekly Standerd^ our verile organ that is ethelred by all ^'^
|
|
@ -0,0 +1,2 @@
|
|||
Sister demo for Finnegan's wake for use on lynx/goerli testnet.
|
||||
Alice and Bob API cleanup compelled by EthDenver 2021.
|
|
@ -213,9 +213,8 @@ class ContractAdministrator(NucypherTokenActor):
|
|||
def __init__(self,
|
||||
registry: BaseContractRegistry,
|
||||
deployer_address: str = None,
|
||||
client_password: str = None,
|
||||
signer: Signer = None,
|
||||
is_transacting: bool = True, # FIXME: Workaround to be able to build MultiSig TXs
|
||||
is_transacting: bool = True,
|
||||
economics: BaseEconomics = None):
|
||||
"""
|
||||
Note: super() is not called here to avoid setting the token agent. TODO: call super but use "bare mode" without token agent. #1510
|
||||
|
@ -232,10 +231,10 @@ class ContractAdministrator(NucypherTokenActor):
|
|||
|
||||
# Powers
|
||||
if is_transacting:
|
||||
self.deployer_power = TransactingPower(signer=signer,
|
||||
password=client_password,
|
||||
account=deployer_address,
|
||||
cache=True)
|
||||
if not signer:
|
||||
raise ValueError('signer is required to make a transacting ContractAdministrator.')
|
||||
self.deployer_power = TransactingPower(signer=signer, account=deployer_address)
|
||||
|
||||
self.transacting_power = self.deployer_power
|
||||
self.transacting_power.activate()
|
||||
else:
|
||||
|
@ -253,7 +252,7 @@ class ContractAdministrator(NucypherTokenActor):
|
|||
def recruit_sidekick(self, sidekick_address: str, sidekick_password: str):
|
||||
self.sidekick_power = TransactingPower(account=sidekick_address, password=sidekick_password, cache=True)
|
||||
if self.sidekick_power.is_device:
|
||||
raise ValueError("Holy Wallet! Sidekicks can only be SW accounts")
|
||||
raise ValueError("Holy Wallet! Sidekicks can only be SW accounts.")
|
||||
self.sidekick_address = sidekick_address
|
||||
|
||||
def activate_deployer(self, refresh: bool = True):
|
||||
|
@ -404,15 +403,16 @@ class Trustee(MultiSigActor):
|
|||
|
||||
def __init__(self,
|
||||
checksum_address: str,
|
||||
client_password: str = None,
|
||||
is_transacting: bool,
|
||||
signer: Optional[Signer] = None,
|
||||
*args, **kwargs):
|
||||
super().__init__(checksum_address=checksum_address, *args, **kwargs)
|
||||
self.authorizations = dict()
|
||||
self.executive_addresses = tuple(
|
||||
self.multisig_agent.owners) # TODO: Investigate unresolved reference to .owners (linter)
|
||||
if client_password: # TODO: Consider an is_transacting parameter
|
||||
self.transacting_power = TransactingPower(password=client_password,
|
||||
account=checksum_address)
|
||||
self.executive_addresses = tuple(self.multisig_agent.owners)
|
||||
if is_transacting:
|
||||
if not signer:
|
||||
raise ValueError('signer is required to create a transacting Trustee.')
|
||||
self.transacting_power = TransactingPower(account=checksum_address, signer=signer)
|
||||
self.transacting_power.activate()
|
||||
|
||||
def add_authorization(self, authorization, proposal: Proposal) -> str:
|
||||
|
@ -495,7 +495,6 @@ class Executive(MultiSigActor):
|
|||
def __init__(self,
|
||||
checksum_address: str,
|
||||
signer: Signer = None,
|
||||
client_password: str = None,
|
||||
*args, **kwargs):
|
||||
super().__init__(checksum_address=checksum_address, *args, **kwargs)
|
||||
|
||||
|
@ -504,9 +503,7 @@ class Executive(MultiSigActor):
|
|||
f"Current owners are {self.multisig_agent.owners}")
|
||||
self.signer = signer
|
||||
if signer:
|
||||
self.transacting_power = TransactingPower(signer=signer,
|
||||
password=client_password,
|
||||
account=checksum_address)
|
||||
self.transacting_power = TransactingPower(signer=signer, account=checksum_address)
|
||||
self.transacting_power.activate()
|
||||
|
||||
def authorize_proposal(self, proposal) -> Authorization:
|
||||
|
@ -1645,7 +1642,6 @@ class Bidder(NucypherTokenActor):
|
|||
checksum_address: str,
|
||||
transacting: bool = True,
|
||||
signer: Signer = None,
|
||||
client_password: str = None,
|
||||
*args, **kwargs):
|
||||
|
||||
super().__init__(checksum_address=checksum_address, *args, **kwargs)
|
||||
|
@ -1655,9 +1651,9 @@ class Bidder(NucypherTokenActor):
|
|||
self.economics = EconomicsFactory.get_economics(registry=self.registry)
|
||||
|
||||
if transacting:
|
||||
self.transacting_power = TransactingPower(signer=signer,
|
||||
password=client_password,
|
||||
account=checksum_address)
|
||||
if not signer:
|
||||
raise ValueError('signer is required to init a transacting Bidder.')
|
||||
self.transacting_power = TransactingPower(signer=signer, account=checksum_address)
|
||||
self.transacting_power.activate()
|
||||
|
||||
self._all_bonus_bidders = None
|
||||
|
@ -1908,14 +1904,11 @@ class DaoActor(BaseActor):
|
|||
checksum_address: ChecksumAddress,
|
||||
registry=None,
|
||||
signer: Signer = None,
|
||||
client_password: str = None,
|
||||
transacting: bool = True):
|
||||
super().__init__(registry=registry, domain=network, checksum_address=checksum_address)
|
||||
self.dao_registry = DAORegistry(network=network)
|
||||
if transacting: # TODO: This logic is repeated in Bidder and possible others.
|
||||
self.transacting_power = TransactingPower(signer=signer,
|
||||
password=client_password,
|
||||
account=checksum_address)
|
||||
self.transacting_power = TransactingPower(signer=signer, account=checksum_address)
|
||||
self.transacting_power.activate()
|
||||
|
||||
|
||||
|
|
|
@ -355,11 +355,6 @@ class KeystoreSigner(Signer):
|
|||
Decrypt the signing material from the key metadata file and cache it on
|
||||
the keystore instance is decryption is successful.
|
||||
"""
|
||||
if not password:
|
||||
# It is possible that password is None here passed from the above layer
|
||||
# causing Account.decrypt to crash, expecting a value for password.
|
||||
raise self.AccessDenied('No password supplied to unlock account.')
|
||||
|
||||
if not self.__signers.get(account):
|
||||
try:
|
||||
key_metadata = self.__keys[account]
|
||||
|
@ -368,6 +363,12 @@ class KeystoreSigner(Signer):
|
|||
try:
|
||||
signing_key = Account.from_key(Account.decrypt(key_metadata, password))
|
||||
self.__signers[account] = signing_key
|
||||
except TypeError:
|
||||
if not password:
|
||||
# It is possible that password is None here passed from the above layer
|
||||
# causing Account.decrypt to crash, expecting a value for password.
|
||||
raise self.AccessDenied('No password supplied to unlock account.')
|
||||
raise
|
||||
except ValueError as e:
|
||||
raise self.AccessDenied("Invalid or incorrect signer password.") from e
|
||||
return True
|
||||
|
|
|
@ -116,8 +116,6 @@ class Alice(Character, BlockchainPolicyAuthor):
|
|||
|
||||
# Ownership
|
||||
checksum_address: str = None,
|
||||
client_password: str = None,
|
||||
cache_password: bool = False,
|
||||
|
||||
# M of N
|
||||
m: int = None,
|
||||
|
@ -164,10 +162,8 @@ class Alice(Character, BlockchainPolicyAuthor):
|
|||
|
||||
if is_me and not federated_only: # TODO: #289
|
||||
blockchain = BlockchainInterfaceFactory.get_interface(provider_uri=self.provider_uri)
|
||||
self.transacting_power = TransactingPower(account=self.checksum_address,
|
||||
password=client_password,
|
||||
cache=cache_password,
|
||||
signer=signer or Web3Signer(blockchain.client))
|
||||
signer = signer or Web3Signer(blockchain.client) # fallback to web3 provider by default for Alice.
|
||||
self.transacting_power = TransactingPower(account=self.checksum_address, signer=signer)
|
||||
|
||||
self._crypto_power.consume_power_up(self.transacting_power)
|
||||
BlockchainPolicyAuthor.__init__(self,
|
||||
|
@ -176,11 +172,12 @@ class Alice(Character, BlockchainPolicyAuthor):
|
|||
duration_periods=duration_periods,
|
||||
checksum_address=checksum_address)
|
||||
|
||||
if is_me and controller:
|
||||
self.make_cli_controller()
|
||||
|
||||
self.log = Logger(self.__class__.__name__)
|
||||
self.log.info(self.banner)
|
||||
if is_me:
|
||||
if controller:
|
||||
self.make_cli_controller()
|
||||
self.log.info(self.banner)
|
||||
|
||||
self.active_policies = dict()
|
||||
self.revocation_kits = dict()
|
||||
|
@ -493,8 +490,18 @@ class Bob(Character):
|
|||
def __init__(self, evidence: List):
|
||||
self.evidence = evidence
|
||||
|
||||
def __init__(self, treasure_maps: Optional[Dict] = None, controller: bool = True, *args, **kwargs) -> None:
|
||||
Character.__init__(self, known_node_class=Ursula, *args, **kwargs)
|
||||
def __init__(self,
|
||||
is_me: bool = True,
|
||||
treasure_maps: Optional[Dict] = None,
|
||||
controller: bool = True,
|
||||
verify_node_bonding: bool = False,
|
||||
*args, **kwargs) -> None:
|
||||
|
||||
Character.__init__(self,
|
||||
is_me=is_me,
|
||||
known_node_class=Ursula,
|
||||
verify_node_bonding=verify_node_bonding,
|
||||
*args, **kwargs)
|
||||
|
||||
if controller:
|
||||
self.make_cli_controller()
|
||||
|
@ -507,7 +514,8 @@ class Bob(Character):
|
|||
self._completed_work_orders = WorkOrderHistory()
|
||||
|
||||
self.log = Logger(self.__class__.__name__)
|
||||
self.log.info(self.banner)
|
||||
if is_me:
|
||||
self.log.info(self.banner)
|
||||
|
||||
def get_card(self) -> 'Card':
|
||||
from nucypher.policy.identity import Card
|
||||
|
@ -801,15 +809,23 @@ class Bob(Character):
|
|||
return True, cfrags
|
||||
|
||||
def retrieve(self,
|
||||
|
||||
# Policy
|
||||
*message_kits: UmbralMessageKit,
|
||||
alice_verifying_key: UmbralPublicKey,
|
||||
alice_verifying_key: Union[UmbralPublicKey, bytes],
|
||||
label: bytes,
|
||||
|
||||
# Source Authentication
|
||||
enrico: "Enrico" = None,
|
||||
policy_encrypting_key: UmbralPublicKey = None,
|
||||
|
||||
# Retrieval Behaviour
|
||||
retain_cfrags: bool = False,
|
||||
use_attached_cfrags: bool = False,
|
||||
use_precedent_work_orders: bool = False,
|
||||
policy_encrypting_key: UmbralPublicKey = None,
|
||||
treasure_map: Union['TreasureMap', bytes] = None):
|
||||
treasure_map: Union['TreasureMap', bytes] = None
|
||||
|
||||
) -> List[bytes]:
|
||||
|
||||
# Try our best to get an UmbralPublicKey from input
|
||||
alice_verifying_key = UmbralPublicKey.from_bytes(bytes(alice_verifying_key))
|
||||
|
@ -833,7 +849,12 @@ class Bob(Character):
|
|||
# self.treasure_maps[treasure_map.public_id()] = treasure_map # TODO: Can we?
|
||||
else:
|
||||
map_id = self.construct_map_id(alice_verifying_key, label)
|
||||
treasure_map = self.treasure_maps[map_id]
|
||||
try:
|
||||
treasure_map = self.treasure_maps[map_id]
|
||||
except KeyError:
|
||||
# If the treasure map is not known, join the policy as part of retrieval.
|
||||
self.join_policy(label=label, alice_verifying_key=alice_verifying_key)
|
||||
treasure_map = self.treasure_maps[map_id]
|
||||
|
||||
_unknown_ursulas, _known_ursulas, m = self.follow_treasure_map(treasure_map=treasure_map, block=True)
|
||||
|
||||
|
@ -842,8 +863,7 @@ class Bob(Character):
|
|||
|
||||
# Normalization
|
||||
for message in message_kits:
|
||||
message.ensure_correct_sender(enrico=enrico,
|
||||
policy_encrypting_key=policy_encrypting_key)
|
||||
message.ensure_correct_sender(enrico=enrico, policy_encrypting_key=policy_encrypting_key)
|
||||
|
||||
# Sanity check: If we're not using attached cfrags, we don't want a Capsule which has them.
|
||||
if not use_attached_cfrags and any(len(message.capsule) > 0 for message in message_kits):
|
||||
|
@ -1450,6 +1470,18 @@ class Ursula(Teacher, Character, Worker):
|
|||
seed_uri = f'{seednode_metadata.checksum_address}@{seednode_metadata.rest_host}:{seednode_metadata.rest_port}'
|
||||
return cls.from_seed_and_stake_info(seed_uri=seed_uri, *args, **kwargs)
|
||||
|
||||
@classmethod
|
||||
def seednode_for_network(cls, network: str) -> 'Ursula':
|
||||
"""Returns a default seednode ursula for a given network."""
|
||||
try:
|
||||
url = RestMiddleware.TEACHER_NODES[network][0]
|
||||
except KeyError:
|
||||
raise ValueError(f'"{network}" is not a known network.')
|
||||
except IndexError:
|
||||
raise ValueError(f'No default seednodes available for "{network}".')
|
||||
ursula = cls.from_seed_and_stake_info(seed_uri=url)
|
||||
return ursula
|
||||
|
||||
@classmethod
|
||||
def from_teacher_uri(cls,
|
||||
federated_only: bool,
|
||||
|
@ -1503,7 +1535,7 @@ class Ursula(Teacher, Character, Worker):
|
|||
#
|
||||
|
||||
# Parse node URI
|
||||
host, port, checksum_address = parse_node_uri(seed_uri)
|
||||
host, port, staker_address = parse_node_uri(seed_uri)
|
||||
|
||||
# Fetch the hosts TLS certificate and read the common name
|
||||
try:
|
||||
|
@ -1529,19 +1561,18 @@ class Ursula(Teacher, Character, Worker):
|
|||
)
|
||||
|
||||
# Check the node's stake (optional)
|
||||
if minimum_stake > 0 and not federated_only:
|
||||
if minimum_stake > 0 and staker_address and not federated_only:
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=registry)
|
||||
seednode_stake = staking_agent.get_locked_tokens(staker_address=checksum_address)
|
||||
seednode_stake = staking_agent.get_locked_tokens(staker_address=staker_address)
|
||||
if seednode_stake < minimum_stake:
|
||||
raise Learner.NotATeacher(
|
||||
f"{checksum_address} is staking less than the specified minimum stake value ({minimum_stake}).")
|
||||
raise Learner.NotATeacher(f"{staker_address} is staking less than the specified minimum stake value ({minimum_stake}).")
|
||||
|
||||
# OK - everyone get out
|
||||
temp_node_storage.forget()
|
||||
return potential_seed_node
|
||||
|
||||
@classmethod
|
||||
def payload_splitter(cls, splittable, partial=False):
|
||||
def payload_splitter(cls, splittable, partial: bool = False):
|
||||
splitter = BytestringKwargifier(
|
||||
_receiver=cls.from_processed_bytes,
|
||||
_partial_receiver=NodeSprout,
|
||||
|
@ -1549,7 +1580,10 @@ class Ursula(Teacher, Character, Worker):
|
|||
domain=VariableLengthBytestring,
|
||||
timestamp=(int, 4, {'byteorder': 'big'}),
|
||||
interface_signature=Signature,
|
||||
decentralized_identity_evidence=VariableLengthBytestring, # FIXME: Fixed length doesn't work with federated. It was LENGTH_ECDSA_SIGNATURE_WITH_RECOVERY,
|
||||
|
||||
# FIXME: Fixed length doesn't work with federated. It was LENGTH_ECDSA_SIGNATURE_WITH_RECOVERY,
|
||||
decentralized_identity_evidence=VariableLengthBytestring,
|
||||
|
||||
verifying_key=(UmbralPublicKey, PUBLIC_KEY_LENGTH),
|
||||
encrypting_key=(UmbralPublicKey, PUBLIC_KEY_LENGTH),
|
||||
certificate=(load_pem_x509_certificate, VariableLengthBytestring, {"backend": default_backend()}),
|
||||
|
@ -1736,19 +1770,25 @@ class Enrico(Character):
|
|||
_interface_class = EnricoInterface
|
||||
_default_crypto_powerups = [SigningPower]
|
||||
|
||||
def __init__(self, policy_encrypting_key=None, controller: bool = True, *args, **kwargs):
|
||||
def __init__(self,
|
||||
is_me: bool = True,
|
||||
policy_encrypting_key: Optional[UmbralPublicKey] = None,
|
||||
controller: bool = True,
|
||||
*args, **kwargs):
|
||||
|
||||
self._policy_pubkey = policy_encrypting_key
|
||||
|
||||
# Enrico never uses the blockchain, hence federated_only)
|
||||
# Enrico never uses the blockchain (hence federated_only)
|
||||
kwargs['federated_only'] = True
|
||||
kwargs['known_node_class'] = None
|
||||
super().__init__(*args, **kwargs)
|
||||
super().__init__(is_me=is_me, *args, **kwargs)
|
||||
|
||||
if controller:
|
||||
self.make_cli_controller()
|
||||
|
||||
self.log = Logger(f'{self.__class__.__name__}-{bytes(self.public_keys(SigningPower)).hex()[:6]}')
|
||||
self.log.info(self.banner.format(policy_encrypting_key))
|
||||
if is_me:
|
||||
self.log.info(self.banner.format(policy_encrypting_key))
|
||||
|
||||
def encrypt_message(self, plaintext: bytes) -> Tuple[UmbralMessageKit, Signature]:
|
||||
# TODO: #2107 Rename to "encrypt"
|
||||
|
|
|
@ -15,16 +15,17 @@ You should have received a copy of the GNU Affero General Public License
|
|||
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
from copy import copy
|
||||
|
||||
import tempfile
|
||||
from eth_tester.exceptions import ValidationError
|
||||
from unittest.mock import patch
|
||||
|
||||
from eth_tester.exceptions import ValidationError
|
||||
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.characters.lawful import Alice, Ursula
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
from nucypher.crypto.api import encrypt_and_sign
|
||||
from nucypher.crypto.constants import HRAC_LENGTH
|
||||
from nucypher.crypto.powers import CryptoPower, SigningPower, DecryptingPower, TransactingPower
|
||||
from nucypher.exceptions import DevelopmentInstallationRequired
|
||||
from nucypher.policy.collections import SignedTreasureMap
|
||||
|
@ -70,8 +71,9 @@ class Vladimir(Ursula):
|
|||
if claim_signing_key:
|
||||
crypto_power.consume_power_up(SigningPower(public_key=target_ursula.stamp.as_umbral_pubkey()))
|
||||
|
||||
blockchain = target_ursula.policy_agent.blockchain
|
||||
if attach_transacting_key:
|
||||
cls.attach_transacting_key(blockchain=target_ursula.policy_agent.blockchain)
|
||||
cls.attach_transacting_key(blockchain=blockchain)
|
||||
|
||||
db_filepath = tempfile.mkdtemp(prefix='Vladimir')
|
||||
|
||||
|
@ -87,6 +89,7 @@ class Vladimir(Ursula):
|
|||
network_middleware=cls.network_middleware,
|
||||
checksum_address=cls.fraud_address,
|
||||
worker_address=cls.fraud_address,
|
||||
signer=Web3Signer(blockchain.client),
|
||||
######### Asshole.
|
||||
timestamp=target_ursula._timestamp,
|
||||
interface_signature=target_ursula._interface_signature,
|
||||
|
|
|
@ -281,7 +281,6 @@ class AliceCharacterOptions:
|
|||
unlock_keyring=not config.dev_mode,
|
||||
teacher_uri=self.teacher_uri,
|
||||
min_stake=self.min_stake,
|
||||
client_password=client_password,
|
||||
start_learning_now=load_seednodes,
|
||||
lonely=self.config_options.lonely)
|
||||
return ALICE
|
||||
|
|
|
@ -92,7 +92,6 @@ class DaoOptions: # TODO: This class is essentially the same that WorkLock opti
|
|||
actor = EmergencyResponseManager(checksum_address=self.participant_address, # bomberos
|
||||
network=self.network,
|
||||
registry=registry,
|
||||
client_password=client_password,
|
||||
signer=signer,
|
||||
transacting=transacting)
|
||||
return actor
|
||||
|
|
|
@ -200,15 +200,14 @@ class ActorOptions:
|
|||
click.confirm(CONFIRM_SELECTED_ACCOUNT.format(address=deployer_address), abort=True)
|
||||
|
||||
is_clef = ClefSigner.is_valid_clef_uri(self.signer_uri)
|
||||
eth_password_is_needed = not self.hw_wallet and not deployer_interface.client.is_local and not is_clef
|
||||
if eth_password_is_needed:
|
||||
password_required = not self.hw_wallet and not deployer_interface.client.is_local and not is_clef
|
||||
if password_required:
|
||||
password = get_client_password(checksum_address=deployer_address)
|
||||
|
||||
# Produce Actor
|
||||
testnet = deployer_interface.client.chain_name != PUBLIC_CHAINS[1] # Mainnet
|
||||
signer = Signer.from_signer_uri(self.signer_uri, testnet=testnet) if self.signer_uri else None
|
||||
ADMINISTRATOR = ContractAdministrator(registry=local_registry,
|
||||
client_password=password,
|
||||
deployer_address=deployer_address,
|
||||
is_transacting=is_transacting,
|
||||
signer=signer)
|
||||
|
|
|
@ -161,7 +161,7 @@ class FelixCharacterOptions:
|
|||
envvar=NUCYPHER_ENVVAR_WORKER_ETH_PASSWORD)
|
||||
|
||||
# Produce Felix
|
||||
FELIX = felix_config.produce(domain=self.config_options.domain, client_password=client_password)
|
||||
FELIX = felix_config.produce(domain=self.config_options.domain)
|
||||
FELIX.make_web_app() # attach web application, but dont start service
|
||||
|
||||
return FELIX
|
||||
|
|
|
@ -110,8 +110,7 @@ class MultiSigOptions:
|
|||
client_password = get_client_password(checksum_address=self.checksum_address)
|
||||
executive = Executive(checksum_address=self.checksum_address,
|
||||
registry=registry,
|
||||
signer=ClefSigner(self.signer_uri),
|
||||
client_password=client_password)
|
||||
signer=ClefSigner(self.signer_uri))
|
||||
return executive
|
||||
|
||||
def create_executive(self, registry) -> Executive: # TODO: Reconsider this method: Executives don't transact, just sign.
|
||||
|
@ -125,7 +124,7 @@ class MultiSigOptions:
|
|||
is_clef = ClefSigner.is_valid_clef_uri(self.signer_uri)
|
||||
if transacting and not self.hw_wallet and not is_clef:
|
||||
client_password = get_client_password(checksum_address=self.checksum_address)
|
||||
trustee = Trustee(checksum_address=self.checksum_address, registry=registry, client_password=client_password)
|
||||
trustee = Trustee(checksum_address=self.checksum_address, registry=registry)
|
||||
return trustee
|
||||
|
||||
def create_trustee(self, registry) -> Trustee:
|
||||
|
|
|
@ -264,11 +264,11 @@ class UrsulaCharacterOptions:
|
|||
try:
|
||||
URSULA = make_cli_character(character_config=ursula_config,
|
||||
emitter=emitter,
|
||||
client_password=client_password,
|
||||
min_stake=self.min_stake,
|
||||
teacher_uri=self.teacher_uri,
|
||||
unlock_keyring=not self.config_options.dev,
|
||||
lonely=self.config_options.lonely,
|
||||
client_password=client_password,
|
||||
start_learning_now=load_seednodes)
|
||||
return ursula_config, URSULA
|
||||
|
||||
|
|
|
@ -114,17 +114,19 @@ class WorkLockOptions:
|
|||
def __create_bidder(self,
|
||||
registry,
|
||||
transacting: bool = True,
|
||||
hw_wallet: bool = False) -> Bidder:
|
||||
hw_wallet: bool = False
|
||||
) -> Bidder:
|
||||
|
||||
client_password = None
|
||||
is_clef = ClefSigner.is_valid_clef_uri(self.signer_uri)
|
||||
if transacting and not is_clef and not hw_wallet:
|
||||
client_password = get_client_password(checksum_address=self.bidder_address)
|
||||
testnet = self.network != NetworksInventory.MAINNET
|
||||
signer = Signer.from_signer_uri(self.signer_uri, testnet=testnet) if self.signer_uri else None
|
||||
password_required = (not is_clef and not hw_wallet)
|
||||
if signer and transacting and password_required:
|
||||
client_password = get_client_password(checksum_address=self.bidder_address)
|
||||
signer.unlock_account(account=self.bidder_address, password=client_password)
|
||||
|
||||
bidder = Bidder(checksum_address=self.bidder_address,
|
||||
registry=registry,
|
||||
client_password=client_password,
|
||||
signer=signer,
|
||||
transacting=transacting)
|
||||
return bidder
|
||||
|
|
|
@ -55,7 +55,7 @@ def make_cli_character(character_config,
|
|||
emitter,
|
||||
unlock_keyring: bool = True,
|
||||
teacher_uri: str = None,
|
||||
min_stake: int = 0, # We not using this anymore? Where is it hooked up?
|
||||
min_stake: int = 0,
|
||||
**config_args) -> Character:
|
||||
|
||||
#
|
||||
|
@ -79,11 +79,13 @@ def make_cli_character(character_config,
|
|||
|
||||
# Produce Character
|
||||
if teacher_uri:
|
||||
maybe_sage_node = character_config.known_node_class.from_teacher_uri(teacher_uri=teacher_uri,
|
||||
min_stake=0, # TODO: Where to get this?
|
||||
federated_only=character_config.federated_only,
|
||||
network_middleware=character_config.network_middleware,
|
||||
registry=character_config.registry)
|
||||
maybe_sage_node = character_config.known_node_class.from_teacher_uri(
|
||||
teacher_uri=teacher_uri,
|
||||
min_stake=min_stake,
|
||||
federated_only=character_config.federated_only,
|
||||
network_middleware=character_config.network_middleware,
|
||||
registry=character_config.registry
|
||||
)
|
||||
sage_nodes.append(maybe_sage_node)
|
||||
|
||||
CHARACTER = character_config(known_nodes=sage_nodes,
|
||||
|
|
|
@ -112,7 +112,7 @@ class TransactingPower(CryptoPowerUp):
|
|||
@validate_checksum_address
|
||||
def __init__(self,
|
||||
account: str,
|
||||
signer: Signer = None,
|
||||
signer: Signer,
|
||||
password: str = None,
|
||||
cache: bool = False):
|
||||
"""
|
||||
|
@ -121,9 +121,7 @@ class TransactingPower(CryptoPowerUp):
|
|||
|
||||
# Auth
|
||||
if not signer:
|
||||
# TODO: Consider making this required
|
||||
blockchain = BlockchainInterfaceFactory.get_interface()
|
||||
signer = Web3Signer(client=blockchain.client)
|
||||
raise ValueError('signer is required to init a TransactingPower.')
|
||||
self._signer = signer
|
||||
self.__account = account
|
||||
self.__password = password
|
||||
|
@ -186,6 +184,8 @@ class TransactingPower(CryptoPowerUp):
|
|||
|
||||
def unlock_account(self, password: str = None, duration: int = None) -> bool:
|
||||
"""Unlocks the account with provided or cached password."""
|
||||
if self.is_unlocked:
|
||||
return True
|
||||
password = password or self.__password
|
||||
result = self._signer.unlock_account(self.__account,
|
||||
password=password,
|
||||
|
|
|
@ -237,7 +237,6 @@ class Learner:
|
|||
self._discovery_canceller = DiscoveryCanceller()
|
||||
|
||||
if not node_storage:
|
||||
# Fallback storage backend
|
||||
node_storage = self.__DEFAULT_NODE_STORAGE(federated_only=self.federated_only)
|
||||
self.node_storage = node_storage
|
||||
if save_metadata and node_storage is NO_STORAGE_AVAILIBLE:
|
||||
|
@ -415,7 +414,7 @@ class Learner:
|
|||
try:
|
||||
node.verify_node(force=force_verification_recheck,
|
||||
network_middleware_client=self.network_middleware.client,
|
||||
registry=registry) # composed on character subclass, determines operating mode
|
||||
registry=registry)
|
||||
except SSLError:
|
||||
# TODO: Bucket this node as having bad TLS info - maybe it's an update that hasn't fully propagated? 567
|
||||
return False
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
You should have received a copy of the GNU Affero General Public License
|
||||
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
from eth_typing import HexStr
|
||||
from web3 import Web3
|
||||
from web3._utils.abi import get_constructor_abi, merge_args_and_kwargs
|
||||
|
@ -21,6 +23,7 @@ from web3._utils.contracts import encode_abi
|
|||
from web3.contract import ContractConstructor
|
||||
|
||||
|
||||
|
||||
def to_bytes32(value=None, hexstr=None) -> bytes:
|
||||
return Web3.toBytes(primitive=value, hexstr=hexstr).rjust(32, b'\0')
|
||||
|
||||
|
@ -58,3 +61,17 @@ def encode_constructor_arguments(web3: Web3,
|
|||
else:
|
||||
data = None
|
||||
return data
|
||||
|
||||
|
||||
def connect_web3_provider(provider_uri: str) -> None:
|
||||
"""
|
||||
Convenience function for connecting to an ethereum provider now.
|
||||
This may be used to optimize the startup time of some applications by
|
||||
establishing the connection eagarly.
|
||||
"""
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
|
||||
|
||||
if not BlockchainInterfaceFactory.is_interface_initialized(provider_uri=provider_uri):
|
||||
BlockchainInterfaceFactory.initialize_interface(provider_uri=provider_uri)
|
||||
interface = BlockchainInterfaceFactory.get_interface(provider_uri=provider_uri)
|
||||
interface.connect()
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
version: '3'
|
||||
|
||||
# USAGE
|
||||
# docker-compose run nucypher-circle-dev bash download_finnegans_wake.sh
|
||||
# docker-compose run nucypher-circle-dev python finnegans-wake-demo.py 172.29.1.3:11500
|
||||
|
||||
services:
|
||||
|
@ -17,6 +16,8 @@ services:
|
|||
networks:
|
||||
nucypher_circle_net:
|
||||
ipv4_address: 172.29.1.0
|
||||
environment:
|
||||
- FINNEGANS_WAKE_PATH=finnegans_wake_demo/finnegans-wake-excerpt.txt
|
||||
circleursula1:
|
||||
ports:
|
||||
- 11500
|
||||
|
@ -148,8 +149,6 @@ services:
|
|||
ipv4_address: 172.29.1.12
|
||||
container_name: circleursula12
|
||||
|
||||
|
||||
|
||||
networks:
|
||||
nucypher_circle_net:
|
||||
ipam:
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# runs in docker on circle ci
|
||||
|
||||
set -e
|
||||
/code/examples/finnegans_wake_demo/download_finnegans_wake.sh
|
||||
python /code/examples/finnegans_wake_demo/finnegans-wake-demo.py 172.29.1.3:11500
|
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# runs in docker on circle ci
|
||||
|
||||
set -e
|
||||
python /code/examples/finnegans_wake_demo/finnegans-wake-demo-federated.py 172.29.1.3:11500
|
|
@ -11,7 +11,7 @@ cd "${0%/*}"
|
|||
echo "working in directory: $PWD"
|
||||
|
||||
# run some ursulas
|
||||
docker-compose up -d
|
||||
docker-compose up -d --build
|
||||
|
||||
# Wait to ensure Ursulas are up.
|
||||
echo "War... watisit good for?"
|
||||
|
@ -21,7 +21,7 @@ sleep 3
|
|||
# Run demo
|
||||
echo "Starting Demo"
|
||||
echo "working in directory: $PWD"
|
||||
docker-compose run nucypher-circle-dev bash /code/scripts/circle/download_and_run_finnegans_wake.sh
|
||||
docker-compose run nucypher-circle-dev bash /code/scripts/circle/run_finnegans_wake.sh
|
||||
|
||||
# spit out logs
|
||||
./logOutput.sh
|
||||
|
|
|
@ -20,6 +20,7 @@ import random
|
|||
import pytest
|
||||
from eth_tester.exceptions import TransactionFailed
|
||||
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.blockchain.eth.actors import Bidder
|
||||
from nucypher.blockchain.eth.agents import ContractAgency, StakingEscrowAgent, WorkLockAgent
|
||||
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
||||
|
@ -27,7 +28,7 @@ from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
|||
|
||||
def test_create_bidder(testerchain, test_registry, agency, token_economics):
|
||||
bidder_address = testerchain.unassigned_accounts[0]
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry)
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry, signer=Web3Signer(testerchain.client))
|
||||
assert bidder.checksum_address == bidder_address
|
||||
assert bidder.registry == test_registry
|
||||
|
||||
|
@ -48,7 +49,7 @@ def test_bidding(testerchain, agency, token_economics, test_registry):
|
|||
|
||||
for i, bid in enumerate(initial_bids):
|
||||
bidder_address = testerchain.client.accounts[i]
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry)
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry, signer=Web3Signer(testerchain.client))
|
||||
|
||||
assert bidder.get_deposited_eth == 0
|
||||
receipt = bidder.place_bid(value=bid)
|
||||
|
@ -61,7 +62,7 @@ def test_cancel_bid(testerchain, agency, token_economics, test_registry):
|
|||
testerchain.time_travel(seconds=token_economics.bidding_duration+1)
|
||||
|
||||
bidder_address = testerchain.client.accounts[1]
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry)
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry, signer=Web3Signer(testerchain.client))
|
||||
assert bidder.get_deposited_eth # Bid
|
||||
receipt = bidder.cancel_bid() # Cancel
|
||||
assert receipt['status'] == 1
|
||||
|
@ -74,14 +75,14 @@ def test_cancel_bid(testerchain, agency, token_economics, test_registry):
|
|||
|
||||
def test_get_remaining_work(testerchain, agency, token_economics, test_registry):
|
||||
bidder_address = testerchain.client.accounts[0]
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry)
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry, signer=Web3Signer(testerchain.client))
|
||||
remaining = bidder.remaining_work
|
||||
assert remaining
|
||||
|
||||
|
||||
def test_verify_correctness_before_refund(testerchain, agency, token_economics, test_registry):
|
||||
bidder_address = testerchain.client.accounts[0]
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry)
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry, signer=Web3Signer(testerchain.client))
|
||||
worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
|
||||
with pytest.raises(Bidder.CancellationWindowIsOpen):
|
||||
|
@ -99,7 +100,7 @@ def test_verify_correctness_before_refund(testerchain, agency, token_economics,
|
|||
|
||||
def test_force_refund(testerchain, agency, token_economics, test_registry):
|
||||
bidder_address = testerchain.client.accounts[0]
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry)
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry, signer=Web3Signer(testerchain.client))
|
||||
whales = bidder.get_whales()
|
||||
|
||||
# Simulate force refund
|
||||
|
@ -110,7 +111,7 @@ def test_force_refund(testerchain, agency, token_economics, test_registry):
|
|||
new_whales = bidder.get_whales()
|
||||
|
||||
bidder_address = testerchain.client.accounts[1]
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry)
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry, signer=Web3Signer(testerchain.client))
|
||||
worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
|
||||
receipt = bidder.force_refund()
|
||||
|
@ -127,7 +128,7 @@ def test_force_refund(testerchain, agency, token_economics, test_registry):
|
|||
|
||||
def test_verify_correctness(testerchain, agency, token_economics, test_registry):
|
||||
bidder_address = testerchain.client.accounts[0]
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry)
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry, signer=Web3Signer(testerchain.client))
|
||||
worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
|
||||
assert not worklock_agent.bidders_checked()
|
||||
|
@ -143,7 +144,7 @@ def test_verify_correctness(testerchain, agency, token_economics, test_registry)
|
|||
|
||||
def test_withdraw_compensation(testerchain, agency, token_economics, test_registry):
|
||||
bidder_address = testerchain.client.accounts[12]
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry)
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry, signer=Web3Signer(testerchain.client))
|
||||
worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
|
||||
assert worklock_agent.get_available_compensation(checksum_address=bidder_address) > 0
|
||||
|
@ -154,7 +155,7 @@ def test_withdraw_compensation(testerchain, agency, token_economics, test_regist
|
|||
|
||||
def test_claim(testerchain, agency, token_economics, test_registry):
|
||||
bidder_address = testerchain.client.accounts[11]
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry)
|
||||
bidder = Bidder(checksum_address=bidder_address, registry=test_registry, signer=Web3Signer(testerchain.client))
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry)
|
||||
worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import json
|
|||
import pytest
|
||||
import random
|
||||
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.blockchain.eth.actors import ContractAdministrator
|
||||
from nucypher.crypto.powers import TransactingPower
|
||||
from tests.constants import INSECURE_DEVELOPMENT_PASSWORD, NUMBER_OF_ALLOCATIONS_IN_TESTS
|
||||
|
@ -37,11 +38,14 @@ def test_rapid_deployment(token_economics, test_registry, tmpdir, get_random_che
|
|||
|
||||
# TODO: #1092 - TransactingPower
|
||||
blockchain.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
signer=Web3Signer(blockchain.client),
|
||||
account=blockchain.etherbase_account)
|
||||
blockchain.transacting_power.activate()
|
||||
deployer_address = blockchain.etherbase_account
|
||||
|
||||
administrator = ContractAdministrator(deployer_address=deployer_address, registry=test_registry)
|
||||
administrator = ContractAdministrator(deployer_address=deployer_address,
|
||||
signer=Web3Signer(blockchain.client),
|
||||
registry=test_registry)
|
||||
blockchain.bootstrap_network(registry=test_registry)
|
||||
|
||||
all_yall = blockchain.unassigned_accounts
|
||||
|
|
|
@ -15,11 +15,10 @@ 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 pytest
|
||||
from unittest.mock import patch
|
||||
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.blockchain.eth.actors import Trustee
|
||||
from nucypher.blockchain.eth.agents import MultiSigAgent
|
||||
from nucypher.blockchain.eth.deployers import MultiSigDeployer
|
||||
|
||||
|
||||
|
@ -33,10 +32,13 @@ def test_trustee_proposes_multisig_management_operations(testerchain, test_regis
|
|||
for step in multisig_deployer.deployment_steps:
|
||||
assert receipts[step]['status'] == 1
|
||||
|
||||
multisig_agent = multisig_deployer.make_agent() # type: MultiSigAgent
|
||||
multisig_agent = multisig_deployer.make_agent()
|
||||
|
||||
trustee_address = testerchain.unassigned_accounts[-1]
|
||||
trustee = Trustee(checksum_address=trustee_address, registry=test_registry)
|
||||
trustee = Trustee(checksum_address=trustee_address,
|
||||
signer=Web3Signer(testerchain.client),
|
||||
registry=test_registry,
|
||||
is_transacting=True)
|
||||
|
||||
# Propose changing threshold
|
||||
free_payload = {'nonce': 0, 'from': multisig_agent.contract_address, 'gasPrice': 0}
|
||||
|
|
|
@ -256,6 +256,8 @@ def test_staker_collects_staking_reward(testerchain,
|
|||
ursula_decentralized_test_config):
|
||||
token_agent, staking_agent, policy_agent = agency
|
||||
|
||||
testerchain.transacting_power.activate()
|
||||
|
||||
# Give more tokens to staker
|
||||
token_airdrop(token_agent=token_agent,
|
||||
origin=testerchain.etherbase_account,
|
||||
|
@ -263,11 +265,8 @@ def test_staker_collects_staking_reward(testerchain,
|
|||
amount=DEVELOPMENT_TOKEN_AIRDROP_AMOUNT)
|
||||
|
||||
mock_transacting_power_activation(account=staker.checksum_address, password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
|
||||
staker.initialize_stake(amount=NU(token_economics.minimum_allowed_locked, 'NuNit'),
|
||||
# Lock the minimum amount of tokens
|
||||
lock_periods=int(
|
||||
token_economics.minimum_locked_periods)) # ... for the fewest number of periods
|
||||
staker.initialize_stake(amount=NU(token_economics.minimum_allowed_locked, 'NuNit'), # Lock the minimum amount of tokens
|
||||
lock_periods=int(token_economics.minimum_locked_periods)) # ... for the fewest number of periods
|
||||
|
||||
# Get an unused address for a new worker
|
||||
worker_address = testerchain.unassigned_accounts[-1]
|
||||
|
|
|
@ -149,7 +149,6 @@ def test_set_min_fee_rate(testerchain, test_registry, agency, policy_meta):
|
|||
assert policy_agent.get_min_fee_rate(staker) == minimum + 1
|
||||
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('blockchain_ursulas')
|
||||
def test_collect_policy_fee(testerchain, agency, policy_meta, token_economics, mock_transacting_power_activation):
|
||||
token_agent, staking_agent, policy_agent = agency
|
||||
|
@ -159,12 +158,10 @@ def test_collect_policy_fee(testerchain, agency, policy_meta, token_economics, m
|
|||
worker = staking_agent.get_worker_from_staker(staker)
|
||||
|
||||
mock_transacting_power_activation(account=worker, password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
|
||||
old_eth_balance = token_agent.blockchain.client.get_balance(staker)
|
||||
|
||||
for _ in range(token_economics.minimum_locked_periods):
|
||||
staking_agent.commit_to_next_period(worker_address=worker)
|
||||
testerchain.time_travel(periods=1)
|
||||
staking_agent.commit_to_next_period(worker_address=worker)
|
||||
|
||||
mock_transacting_power_activation(account=staker, password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
receipt = agent.collect_policy_fee(collector_address=staker, staker_address=staker)
|
||||
|
|
|
@ -19,6 +19,7 @@ import pytest
|
|||
from constant_sorrow import constants
|
||||
from eth_tester.exceptions import TransactionFailed
|
||||
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.blockchain.eth.actors import Staker
|
||||
from nucypher.blockchain.eth.agents import ContractAgency, NucypherTokenAgent, StakingEscrowAgent
|
||||
from nucypher.blockchain.eth.deployers import (AdjudicatorDeployer, BaseContractDeployer, NucypherTokenDeployer,
|
||||
|
@ -131,7 +132,9 @@ def test_stake_in_idle_network(testerchain, token_economics, test_registry):
|
|||
staker = Staker(is_me=True, checksum_address=account, registry=test_registry)
|
||||
|
||||
# Mock TransactingPower consumption
|
||||
staker.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD, account=staker.checksum_address)
|
||||
staker.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
signer=Web3Signer(testerchain.client),
|
||||
account=staker.checksum_address)
|
||||
staker.transacting_power.activate()
|
||||
|
||||
# Since StakingEscrow hasn't been activated yet, deposit should work but making a commitment must fail
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainDeployerInterface, BlockchainInterfaceFactory
|
||||
from nucypher.blockchain.eth.registry import InMemoryContractRegistry
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.blockchain.eth.sol.compile.constants import TEST_MULTIVERSION_CONTRACTS
|
||||
from nucypher.blockchain.eth.sol.compile.types import SourceBundle
|
||||
from nucypher.crypto.powers import TransactingPower
|
||||
|
@ -49,7 +50,9 @@ def test_deployer_interface_multiversion_contract():
|
|||
BlockchainInterfaceFactory.register_interface(interface=blockchain_interface) # Lets this test run in isolation
|
||||
|
||||
origin = blockchain_interface.client.accounts[0]
|
||||
blockchain_interface.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD, account=origin)
|
||||
blockchain_interface.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
signer=Web3Signer(blockchain_interface.client),
|
||||
account=origin)
|
||||
blockchain_interface.transacting_power.activate()
|
||||
|
||||
# Searching both contract through raw data
|
||||
|
|
|
@ -20,10 +20,10 @@ import pytest
|
|||
from nucypher.blockchain.eth.clients import EthereumClient
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainDeployerInterface
|
||||
from nucypher.blockchain.eth.registry import InMemoryContractRegistry
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.blockchain.eth.sol.compile.compile import multiversion_compile
|
||||
from nucypher.blockchain.eth.sol.compile.constants import TEST_MULTIVERSION_CONTRACTS, SOLIDITY_SOURCE_ROOT
|
||||
from nucypher.blockchain.eth.sol.compile.types import SourceBundle
|
||||
from nucypher.config.constants import NUCYPHER_TEST_DIR
|
||||
from nucypher.crypto.powers import TransactingPower
|
||||
from tests.constants import (
|
||||
DEVELOPMENT_ETH_AIRDROP_AMOUNT,
|
||||
|
@ -112,7 +112,9 @@ def test_multiversion_contract():
|
|||
blockchain_interface._raw_contract_cache = compiled_contracts
|
||||
|
||||
origin = blockchain_interface.client.accounts[0]
|
||||
blockchain_interface.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD, account=origin)
|
||||
blockchain_interface.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
signer=Web3Signer(blockchain_interface.client),
|
||||
account=origin)
|
||||
blockchain_interface.transacting_power.activate()
|
||||
|
||||
# Searching both contract through raw data
|
||||
|
|
|
@ -15,10 +15,12 @@
|
|||
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
import pytest
|
||||
from eth_account._utils.transactions import Transaction
|
||||
from eth_utils import to_checksum_address
|
||||
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.blockchain.eth.agents import NucypherTokenAgent
|
||||
from nucypher.crypto.api import verify_eip_191
|
||||
from nucypher.crypto.powers import TransactingPower
|
||||
|
@ -33,6 +35,7 @@ def test_transacting_power_sign_message(testerchain):
|
|||
# Manually create a TransactingPower
|
||||
eth_address = testerchain.etherbase_account
|
||||
power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
signer=Web3Signer(testerchain.client),
|
||||
account=eth_address)
|
||||
|
||||
# The default state of the account is locked.
|
||||
|
@ -69,6 +72,7 @@ def test_transacting_power_sign_transaction(testerchain):
|
|||
|
||||
eth_address = testerchain.unassigned_accounts[2]
|
||||
power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
signer=Web3Signer(testerchain.client),
|
||||
account=eth_address)
|
||||
|
||||
assert power.is_active is False
|
||||
|
@ -116,6 +120,7 @@ def test_transacting_power_sign_transaction(testerchain):
|
|||
|
||||
# Tear-Down Test
|
||||
power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
signer=Web3Signer(testerchain.client),
|
||||
account=testerchain.etherbase_account)
|
||||
power.activate(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
|
||||
|
@ -134,6 +139,7 @@ def test_transacting_power_sign_agent_transaction(testerchain, agency, test_regi
|
|||
|
||||
# Sign with Transacting Power
|
||||
transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
signer=Web3Signer(testerchain.client),
|
||||
account=testerchain.etherbase_account)
|
||||
transacting_power.activate()
|
||||
signed_raw_transaction = transacting_power.sign_transaction(unsigned_transaction)
|
||||
|
|
|
@ -48,6 +48,7 @@ def test_deploy_single_contract(click_runner, tempfile_path):
|
|||
'--contract-name', NucypherTokenAgent.contract_name,
|
||||
'--registry-infile', tempfile_path,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--debug']
|
||||
|
||||
|
@ -106,6 +107,7 @@ def test_upgrade_contracts(click_runner, test_registry_source_manager, test_regi
|
|||
cli_action = 'upgrade'
|
||||
base_command = ('--registry-infile', registry_filepath,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--confirmations', 1,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--force' # skip registry preflight check for tests
|
||||
|
@ -234,7 +236,9 @@ def test_rollback(click_runner, testerchain, registry_filepath, agency):
|
|||
'--contract-name', contract_name,
|
||||
'--registry-infile', registry_filepath,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--provider', TEST_PROVIDER_URI)
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI
|
||||
)
|
||||
|
||||
user_input = '0\n' + YES_ENTER
|
||||
result = click_runner.invoke(deploy, command, input=user_input, catch_exceptions=False)
|
||||
|
|
|
@ -62,6 +62,7 @@ def test_set_range(click_runner, testerchain, agency_local_registry):
|
|||
minimum, default, maximum = 10, 20, 30
|
||||
status_command = ('set-range',
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--registry-infile', agency_local_registry.filepath,
|
||||
'--minimum', minimum,
|
||||
'--default', default,
|
||||
|
@ -122,6 +123,7 @@ def test_transfer_ownership(click_runner, testerchain, agency_local_registry):
|
|||
'--registry-infile', agency_local_registry.filepath,
|
||||
'--contract-name', STAKING_ESCROW_CONTRACT_NAME,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--target-address', maclane)
|
||||
|
||||
|
@ -146,6 +148,7 @@ def test_transfer_ownership(click_runner, testerchain, agency_local_registry):
|
|||
'--contract-name', STAKING_ESCROW_CONTRACT_NAME,
|
||||
'--registry-infile', agency_local_registry.filepath,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--target-address', michwill)
|
||||
|
||||
|
@ -171,6 +174,7 @@ def test_transfer_ownership_staking_interface_router(click_runner, testerchain,
|
|||
'--registry-infile', agency_local_registry.filepath,
|
||||
'--contract-name', StakingInterfaceDeployer.contract_name,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--target-address', maclane,
|
||||
'--debug')
|
||||
|
@ -200,6 +204,7 @@ def test_bare_contract_deployment_to_alternate_registry(click_runner, agency_loc
|
|||
'--contract-name', StakingEscrowDeployer.contract_name,
|
||||
'--mode', 'bare',
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--registry-infile', agency_local_registry.filepath,
|
||||
'--registry-outfile', ALTERNATE_REGISTRY_FILEPATH,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
|
@ -246,6 +251,7 @@ def test_manual_proxy_retargeting(monkeypatch, testerchain, click_runner, token_
|
|||
'--contract-name', StakingEscrowDeployer.contract_name,
|
||||
'--target-address', untargeted_deployment.address,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH,
|
||||
'--confirmations', 4,
|
||||
'--network', TEMPORARY_DOMAIN)
|
||||
|
@ -275,6 +281,7 @@ def test_manual_deployment_of_idle_network(click_runner):
|
|||
'--contract-name', NUCYPHER_TOKEN_CONTRACT_NAME,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
||||
|
||||
result = click_runner.invoke(deploy, command, input=user_input, catch_exceptions=False)
|
||||
|
@ -291,6 +298,7 @@ def test_manual_deployment_of_idle_network(click_runner):
|
|||
'--contract-name', STAKING_ESCROW_CONTRACT_NAME,
|
||||
'--mode', 'init',
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
||||
|
||||
|
@ -304,6 +312,7 @@ def test_manual_deployment_of_idle_network(click_runner):
|
|||
command = ('contracts',
|
||||
'--contract-name', POLICY_MANAGER_CONTRACT_NAME,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
||||
|
||||
|
@ -317,6 +326,7 @@ def test_manual_deployment_of_idle_network(click_runner):
|
|||
command = ('contracts',
|
||||
'--contract-name', ADJUDICATOR_CONTRACT_NAME,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
||||
|
||||
|
@ -331,6 +341,7 @@ def test_manual_deployment_of_idle_network(click_runner):
|
|||
'--contract-name', STAKING_ESCROW_CONTRACT_NAME,
|
||||
'--mode', 'idle',
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
||||
|
||||
|
@ -345,6 +356,7 @@ def test_manual_deployment_of_idle_network(click_runner):
|
|||
'--contract-name', STAKING_ESCROW_CONTRACT_NAME,
|
||||
'--activate',
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import pytest
|
|||
from eth_utils import to_wei
|
||||
from web3 import Web3
|
||||
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.crypto.powers import TransactingPower
|
||||
from nucypher.blockchain.eth.actors import Bidder, Staker
|
||||
from nucypher.blockchain.eth.agents import (
|
||||
|
@ -73,6 +74,7 @@ def test_bid(click_runner, testerchain, agency_local_registry, token_economics,
|
|||
base_command = ('escrow',
|
||||
'--registry-filepath', agency_local_registry.filepath,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--force')
|
||||
|
||||
|
@ -107,6 +109,7 @@ def test_cancel_bid(click_runner, testerchain, agency_local_registry, token_econ
|
|||
'--participant-address', bidder,
|
||||
'--registry-filepath', agency_local_registry.filepath,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--force')
|
||||
|
||||
|
@ -123,6 +126,7 @@ def test_cancel_bid(click_runner, testerchain, agency_local_registry, token_econ
|
|||
'--participant-address', bidder,
|
||||
'--registry-filepath', agency_local_registry.filepath,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--force')
|
||||
|
||||
|
@ -146,6 +150,7 @@ def test_enable_claiming(click_runner, testerchain, agency_local_registry, token
|
|||
'--participant-address', bidder,
|
||||
'--registry-filepath', agency_local_registry.filepath,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--force',
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--gas-limit', 100000)
|
||||
|
@ -165,6 +170,7 @@ def test_claim(click_runner, testerchain, agency_local_registry, token_economics
|
|||
'--participant-address', bidder,
|
||||
'--registry-filepath', agency_local_registry.filepath,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--force')
|
||||
|
||||
|
@ -178,6 +184,7 @@ def test_claim(click_runner, testerchain, agency_local_registry, token_economics
|
|||
'--participant-address', whale,
|
||||
'--registry-filepath', agency_local_registry.filepath,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--force')
|
||||
|
||||
|
@ -201,6 +208,7 @@ def test_remaining_work(click_runner, testerchain, agency_local_registry, token_
|
|||
'--participant-address', bidder,
|
||||
'--registry-filepath', agency_local_registry.filepath,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN)
|
||||
|
||||
result = click_runner.invoke(worklock, command, catch_exceptions=False)
|
||||
|
@ -230,6 +238,7 @@ def test_refund(click_runner, testerchain, agency_local_registry, token_economic
|
|||
worker = Ursula(is_me=True,
|
||||
registry=agency_local_registry,
|
||||
checksum_address=bidder,
|
||||
signer=Web3Signer(testerchain.client),
|
||||
worker_address=worker_address,
|
||||
rest_host=MOCK_IP_ADDRESS,
|
||||
rest_port=select_test_port(),
|
||||
|
@ -255,6 +264,7 @@ def test_refund(click_runner, testerchain, agency_local_registry, token_economic
|
|||
'--participant-address', bidder,
|
||||
'--registry-filepath', agency_local_registry.filepath,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--force')
|
||||
|
||||
|
@ -268,12 +278,15 @@ def test_refund(click_runner, testerchain, agency_local_registry, token_economic
|
|||
|
||||
|
||||
def test_participant_status(click_runner, testerchain, agency_local_registry, token_economics):
|
||||
bidder = Bidder(checksum_address=testerchain.client.accounts[2], registry=agency_local_registry)
|
||||
bidder = Bidder(checksum_address=testerchain.client.accounts[2],
|
||||
signer=Web3Signer(testerchain.client),
|
||||
registry=agency_local_registry)
|
||||
|
||||
command = ('status',
|
||||
'--registry-filepath', agency_local_registry.filepath,
|
||||
'--participant-address', bidder.checksum_address,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--signer', TEST_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN)
|
||||
|
||||
result = click_runner.invoke(worklock, command, catch_exceptions=False)
|
||||
|
|
|
@ -145,9 +145,9 @@ def test_ursula_and_local_keystore_signer_integration(click_runner,
|
|||
|
||||
# Produce an Ursula with a Keystore signer correctly derived from the signer URI, and don't do anything else!
|
||||
mocker.patch.object(StakeList, 'refresh', autospec=True)
|
||||
ursula = ursula_config.produce(client_password=password,
|
||||
commit_now=False,
|
||||
block_until_ready=False)
|
||||
ursula = ursula_config.produce(commit_now=False, block_until_ready=False)
|
||||
ursula.signer.unlock_account(account=worker_account.address, password=password)
|
||||
|
||||
|
||||
try:
|
||||
# Verify the keystore path is still preserved
|
||||
|
|
|
@ -16,32 +16,41 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
|||
"""
|
||||
|
||||
import json
|
||||
import random
|
||||
|
||||
import maya
|
||||
import os
|
||||
import pytest
|
||||
import random
|
||||
import tempfile
|
||||
from web3 import Web3
|
||||
|
||||
from nucypher.blockchain.eth.actors import Staker
|
||||
from nucypher.blockchain.eth.agents import (ContractAgency, NucypherTokenAgent, PreallocationEscrowAgent,
|
||||
StakingEscrowAgent)
|
||||
from nucypher.blockchain.eth.agents import (
|
||||
ContractAgency,
|
||||
NucypherTokenAgent,
|
||||
PreallocationEscrowAgent,
|
||||
StakingEscrowAgent
|
||||
)
|
||||
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
||||
from nucypher.blockchain.eth.deployers import PreallocationEscrowDeployer
|
||||
from nucypher.blockchain.eth.registry import InMemoryAllocationRegistry, IndividualAllocationRegistry
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.blockchain.eth.token import NU, Stake, StakeList
|
||||
from nucypher.characters.lawful import Enrico, Ursula
|
||||
from nucypher.cli.main import nucypher_cli
|
||||
from nucypher.config.characters import UrsulaConfiguration
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
from nucypher.utilities.logging import Logger
|
||||
from tests.constants import (FAKE_PASSWORD_CONFIRMED, INSECURE_DEVELOPMENT_PASSWORD,
|
||||
MOCK_INDIVIDUAL_ALLOCATION_FILEPATH, MOCK_IP_ADDRESS,
|
||||
ONE_YEAR_IN_SECONDS,
|
||||
TEST_PROVIDER_URI)
|
||||
from tests.constants import (
|
||||
FAKE_PASSWORD_CONFIRMED,
|
||||
INSECURE_DEVELOPMENT_PASSWORD,
|
||||
MOCK_INDIVIDUAL_ALLOCATION_FILEPATH,
|
||||
MOCK_IP_ADDRESS,
|
||||
ONE_YEAR_IN_SECONDS,
|
||||
TEST_PROVIDER_URI
|
||||
)
|
||||
from tests.utils.middleware import MockRestMiddleware
|
||||
from tests.utils.ursula import MOCK_KNOWN_URSULAS_CACHE, MOCK_URSULA_STARTING_PORT, select_test_port
|
||||
from tests.utils.ursula import MOCK_KNOWN_URSULAS_CACHE, select_test_port
|
||||
|
||||
|
||||
#
|
||||
|
@ -492,6 +501,7 @@ def test_collect_rewards_integration(click_runner,
|
|||
|
||||
ursula_port = select_test_port()
|
||||
ursula = Ursula(is_me=True,
|
||||
signer=Web3Signer(testerchain.client),
|
||||
checksum_address=staker_address,
|
||||
worker_address=worker_address,
|
||||
registry=agency_local_registry,
|
||||
|
|
|
@ -15,18 +15,20 @@ 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 json
|
||||
import os
|
||||
import random
|
||||
import tempfile
|
||||
from unittest import mock
|
||||
|
||||
import maya
|
||||
import os
|
||||
import random
|
||||
import tempfile
|
||||
from web3 import Web3
|
||||
|
||||
from nucypher.blockchain.eth.actors import Staker
|
||||
from nucypher.blockchain.eth.agents import ContractAgency, StakingEscrowAgent
|
||||
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.blockchain.eth.token import NU, Stake
|
||||
from nucypher.blockchain.eth.utils import prettify_eth_amount
|
||||
from nucypher.characters.lawful import Enrico, Ursula
|
||||
|
@ -35,11 +37,16 @@ from nucypher.cli.main import nucypher_cli
|
|||
from nucypher.config.characters import StakeHolderConfiguration, UrsulaConfiguration
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
from nucypher.utilities.logging import Logger
|
||||
|
||||
from tests.constants import FAKE_PASSWORD_CONFIRMED, FEE_RATE_RANGE, INSECURE_DEVELOPMENT_PASSWORD, MOCK_IP_ADDRESS, \
|
||||
TEST_PROVIDER_URI, YES_ENTER
|
||||
from tests.constants import (
|
||||
FAKE_PASSWORD_CONFIRMED,
|
||||
FEE_RATE_RANGE,
|
||||
INSECURE_DEVELOPMENT_PASSWORD,
|
||||
MOCK_IP_ADDRESS,
|
||||
TEST_PROVIDER_URI,
|
||||
YES_ENTER
|
||||
)
|
||||
from tests.utils.middleware import MockRestMiddleware
|
||||
from tests.utils.ursula import MOCK_KNOWN_URSULAS_CACHE, MOCK_URSULA_STARTING_PORT, select_test_port
|
||||
from tests.utils.ursula import MOCK_KNOWN_URSULAS_CACHE, select_test_port
|
||||
|
||||
|
||||
@mock.patch('nucypher.config.characters.StakeHolderConfiguration.default_filepath', return_value='/non/existent/file')
|
||||
|
@ -562,6 +569,7 @@ def test_collect_rewards_integration(click_runner,
|
|||
ursula_port = select_test_port()
|
||||
ursula = Ursula(is_me=True,
|
||||
checksum_address=staker_address,
|
||||
signer=Web3Signer(testerchain.client),
|
||||
worker_address=worker_address,
|
||||
registry=agency_local_registry,
|
||||
rest_host='127.0.0.1',
|
||||
|
|
|
@ -14,19 +14,26 @@ 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 contextlib
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import requests
|
||||
from constant_sorrow import constants
|
||||
from pathlib import Path
|
||||
from web3.exceptions import ValidationError
|
||||
|
||||
from nucypher.blockchain.eth.deployers import AdjudicatorDeployer, BaseContractDeployer, NucypherTokenDeployer, \
|
||||
PolicyManagerDeployer, StakingEscrowDeployer, WorklockDeployer
|
||||
from nucypher.blockchain.eth.deployers import (
|
||||
AdjudicatorDeployer,
|
||||
BaseContractDeployer,
|
||||
NucypherTokenDeployer,
|
||||
PolicyManagerDeployer,
|
||||
StakingEscrowDeployer,
|
||||
WorklockDeployer
|
||||
)
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainDeployerInterface, BlockchainInterfaceFactory
|
||||
from nucypher.blockchain.eth.registry import InMemoryContractRegistry
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.blockchain.eth.sol.compile.constants import SOLIDITY_SOURCE_ROOT
|
||||
from nucypher.blockchain.eth.sol.compile.types import SourceBundle
|
||||
from nucypher.crypto.powers import TransactingPower
|
||||
|
@ -137,7 +144,9 @@ def test_upgradeability(temp_dir_path):
|
|||
blockchain_interface.connect()
|
||||
origin = blockchain_interface.client.accounts[0]
|
||||
BlockchainInterfaceFactory.register_interface(interface=blockchain_interface)
|
||||
blockchain_interface.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD, account=origin)
|
||||
blockchain_interface.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
signer=Web3Signer(blockchain_interface.client),
|
||||
account=origin)
|
||||
blockchain_interface.transacting_power.activate()
|
||||
|
||||
economics = make_token_economics(blockchain_interface)
|
||||
|
|
|
@ -171,12 +171,13 @@ def test_keystore_locking(mock_account, good_signer, unknown_address, mocker):
|
|||
with pytest.raises(Signer.UnknownAccount):
|
||||
good_signer.unlock_account(account=unknown_address, password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
|
||||
mocker.patch.dict(good_signer._KeystoreSigner__signers, {}, clear=True)
|
||||
|
||||
# Missing password
|
||||
with pytest.raises(Signer.AccessDenied, match='No password supplied to unlock account.'):
|
||||
good_signer.unlock_account(account=mock_account.address, password=None)
|
||||
|
||||
# Wrong password
|
||||
mocker.patch.dict(good_signer._KeystoreSigner__signers, {}, clear=True)
|
||||
with pytest.raises(Signer.AccessDenied, match="Invalid or incorrect signer password."):
|
||||
good_signer.unlock_account(account=mock_account.address, password='imadeupthispassworditisverygood')
|
||||
|
||||
|
|
|
@ -100,8 +100,9 @@ def test_ursula_init_with_local_keystore_signer(click_runner,
|
|||
|
||||
# Produce an ursula with a Keystore signer correctly derived from the signer URI, and dont do anything else!
|
||||
mocker.patch.object(StakeList, 'refresh', autospec=True)
|
||||
ursula = ursula_config.produce(client_password=password,
|
||||
block_until_ready=False)
|
||||
ursula = ursula_config.produce(block_until_ready=False)
|
||||
ursula.signer.unlock_account(account=worker_account.address, password=password)
|
||||
|
||||
|
||||
# Verify the keystore path is still preserved
|
||||
assert isinstance(ursula.signer, KeystoreSigner)
|
||||
|
|
|
@ -24,6 +24,7 @@ import pytest
|
|||
from eth_utils import to_wei
|
||||
from web3 import Web3
|
||||
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.blockchain.eth.actors import Bidder
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainInterface
|
||||
from nucypher.blockchain.eth.utils import prettify_eth_amount
|
||||
|
@ -51,7 +52,8 @@ from tests.mock.agents import MockContractAgent
|
|||
@pytest.fixture()
|
||||
def surrogate_bidder(mock_testerchain, test_registry, mock_worklock_agent):
|
||||
address = mock_testerchain.etherbase_account
|
||||
bidder = Bidder(checksum_address=address, registry=test_registry)
|
||||
signer = Web3Signer(mock_testerchain.client)
|
||||
bidder = Bidder(checksum_address=address, registry=test_registry, signer=signer)
|
||||
return bidder
|
||||
|
||||
|
||||
|
@ -80,9 +82,10 @@ def test_account_selection(click_runner, mocker, mock_testerchain, mock_worklock
|
|||
|
||||
command = ('cancel-escrow',
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
'--signer', MOCK_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN)
|
||||
|
||||
user_input = '\n'.join((str(index), INSECURE_DEVELOPMENT_PASSWORD, YES))
|
||||
user_input = '\n'.join((str(index), INSECURE_DEVELOPMENT_PASSWORD, YES, YES))
|
||||
result = click_runner.invoke(worklock, command, input=user_input, catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
|
||||
|
@ -103,6 +106,7 @@ def bidding_command(token_economics, surrogate_bidder):
|
|||
'--participant-address', surrogate_bidder.checksum_address,
|
||||
'--value', bid_value,
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
'--signer', MOCK_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--force')
|
||||
return command
|
||||
|
@ -197,6 +201,7 @@ def test_valid_bid(click_runner,
|
|||
'--participant-address', surrogate_bidder.checksum_address,
|
||||
'--value', bid_value_in_eth,
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
'--signer', MOCK_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--force')
|
||||
|
||||
|
@ -237,6 +242,7 @@ def test_cancel_bid(click_runner,
|
|||
command = ('cancel-escrow',
|
||||
'--participant-address', surrogate_bidder.checksum_address,
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
'--signer', MOCK_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--force')
|
||||
result = click_runner.invoke(worklock, command, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False)
|
||||
|
@ -303,6 +309,7 @@ def test_enable_claiming(click_runner,
|
|||
command = ('enable-claiming',
|
||||
'--participant-address', surrogate_bidder.checksum_address,
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
'--signer', MOCK_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN)
|
||||
|
||||
gas_limit_1 = 200000
|
||||
|
@ -362,6 +369,7 @@ def test_initial_claim(click_runner,
|
|||
command = ('claim',
|
||||
'--participant-address', bidder_address,
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
'--signer', MOCK_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN)
|
||||
|
||||
# First, let's test that if claiming is not available, command fails
|
||||
|
@ -439,6 +447,7 @@ def test_already_claimed(click_runner,
|
|||
command = ('claim',
|
||||
'--participant-address', surrogate_bidder.checksum_address,
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
'--signer', MOCK_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--force')
|
||||
|
||||
|
@ -470,6 +479,7 @@ def test_remaining_work(click_runner,
|
|||
command = ('remaining-work',
|
||||
'--participant-address', surrogate_bidder.checksum_address,
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
'--signer', MOCK_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN)
|
||||
|
||||
result = click_runner.invoke(worklock, command, catch_exceptions=False)
|
||||
|
@ -496,6 +506,7 @@ def test_refund(click_runner,
|
|||
command = ('refund',
|
||||
'--participant-address', bidder_address,
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
'--signer', MOCK_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN)
|
||||
|
||||
user_input = INSECURE_DEVELOPMENT_PASSWORD + '\n' + YES
|
||||
|
@ -521,6 +532,7 @@ def test_participant_status(click_runner,
|
|||
command = ('status',
|
||||
'--participant-address', surrogate_bidder.checksum_address,
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
'--signer', MOCK_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN)
|
||||
|
||||
result = click_runner.invoke(worklock, command, catch_exceptions=False)
|
||||
|
@ -574,6 +586,7 @@ def test_interactive_new_bid(click_runner,
|
|||
command = ('escrow',
|
||||
'--participant-address', surrogate_bidder.checksum_address,
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
'--signer', MOCK_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,)
|
||||
|
||||
user_input = "\n".join((INSECURE_DEVELOPMENT_PASSWORD, str(wrong_bid_in_eth), str(bid_value_in_eth), YES))
|
||||
|
@ -624,6 +637,7 @@ def test_interactive_increase_bid(click_runner,
|
|||
command = ('escrow',
|
||||
'--participant-address', surrogate_bidder.checksum_address,
|
||||
'--provider', MOCK_PROVIDER_URI,
|
||||
'--signer', MOCK_PROVIDER_URI,
|
||||
'--network', TEMPORARY_DOMAIN,)
|
||||
|
||||
user_input = "\n".join((INSECURE_DEVELOPMENT_PASSWORD, str(bid_value_in_eth), YES))
|
||||
|
|
|
@ -176,7 +176,8 @@ def make_alice(known_nodes: Optional[Set[Ursula]] = None):
|
|||
|
||||
alice_config.initialize(password=INSECURE_PASSWORD)
|
||||
alice_config.keyring.unlock(password=INSECURE_PASSWORD)
|
||||
alice = alice_config.produce(client_password=SIGNER_PASSWORD)
|
||||
alice = alice_config.produce()
|
||||
alice.signer.unlock_account(account=ALICE_ADDRESS, password=SIGNER_PASSWORD)
|
||||
alice.start_learning_loop(now=True)
|
||||
return alice
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ from hexbytes import HexBytes
|
|||
from typing import List, Tuple, Union, Optional
|
||||
from web3 import Web3
|
||||
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.blockchain.economics import BaseEconomics, StandardTokenEconomics
|
||||
from nucypher.blockchain.eth.actors import ContractAdministrator
|
||||
from nucypher.blockchain.eth.deployers import StakingEscrowDeployer
|
||||
|
@ -50,6 +51,9 @@ from constant_sorrow.constants import INIT
|
|||
def token_airdrop(token_agent, amount: NU, origin: str, addresses: List[str]):
|
||||
"""Airdrops tokens from creator address to all other addresses!"""
|
||||
|
||||
signer = Web3Signer(token_agent.blockchain.client)
|
||||
signer.unlock_account(account=origin, password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
|
||||
def txs():
|
||||
args = {'from': origin, 'gasPrice': token_agent.blockchain.client.gas_price}
|
||||
for address in addresses:
|
||||
|
@ -222,13 +226,11 @@ class TesterBlockchain(BlockchainDeployerInterface):
|
|||
testerchain = cls()
|
||||
if not BlockchainInterfaceFactory.is_interface_initialized(provider_uri=testerchain.provider_uri):
|
||||
BlockchainInterfaceFactory.register_interface(interface=testerchain)
|
||||
power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD, account=testerchain.etherbase_account)
|
||||
power.activate()
|
||||
testerchain.transacting_power = power
|
||||
|
||||
origin = testerchain.client.etherbase
|
||||
admin = ContractAdministrator(deployer_address=origin,
|
||||
registry=registry,
|
||||
signer=Web3Signer(testerchain.client),
|
||||
economics=economics or cls.DEFAULT_ECONOMICS)
|
||||
|
||||
gas_limit = None # TODO: Gas management - #842
|
||||
|
|
Loading…
Reference in New Issue