Returning to a single-account BlockchainPower;TODO annotations for BlockchainPower.

pull/1029/head
Kieran Prasch 2019-06-19 18:31:00 -07:00 committed by David Núñez
parent e56245565b
commit 68b8a2735d
12 changed files with 58 additions and 43 deletions

View File

@ -59,7 +59,7 @@ class EthereumContractAgent:
pass
def __init__(self,
blockchain: BlockchainInterface = None,
blockchain: BlockchainInterface,
contract: Contract = None,
transaction_gas: int = None
) -> None:

View File

@ -318,7 +318,7 @@ class BlockchainInterface:
# Broadcast
#
signed_raw_transaction = self.transacting_power.sign_transaction(unsigned_transaction, sender_address)
signed_raw_transaction = self.transacting_power.sign_transaction(unsigned_transaction)
txhash = self.client.w3.eth.sendRawTransaction(signed_raw_transaction)
try:

View File

@ -182,9 +182,9 @@ class Felix(Character, NucypherTokenActor):
self.db_engine = create_engine(f'sqlite:///{self.db_filepath}', convert_unicode=True)
# Blockchain
blockchain_power = BlockchainPower(client=self.blockchain.client)
blockchain_power = BlockchainPower(blockchain=self.blockchain, account=self.checksum_address)
self._crypto_power.consume_power_up(blockchain_power)
# blockchain_power.unlock_account(account=self.checksum_address) # TODO
# blockchain_power.unlock_account(password=None) # TODO: TransactingPower
self.token_agent = NucypherTokenAgent(blockchain=self.blockchain)
self.reserved_addresses = [self.checksum_address, BlockchainInterface.NULL_ADDRESS]

View File

@ -124,9 +124,10 @@ class Alice(Character, PolicyAuthor):
policy_agent=policy_agent,
checksum_address=checksum_address)
blockchain_power = BlockchainPower(client=self.blockchain.client)
# TODO: #1092 - TransactingPower
blockchain_power = BlockchainPower(blockchain=self.blockchain, account=self.checksum_address)
self._crypto_power.consume_power_up(blockchain_power)
self.blockchain.transacting_power = blockchain_power # TODO: #1092
self.blockchain.transacting_power = blockchain_power # TODO: Embed in Powerups
if is_me and controller:
self.controller = self._controller_class(alice=self)
@ -839,7 +840,6 @@ class Ursula(Teacher, Character, Worker):
checksum_address: str = None, # Staker address
worker_address: str = None,
stake_tracker: StakeTracker = None,
staking_agent: StakingEscrowAgent = None,
# Character
password: str = None,
@ -877,7 +877,9 @@ class Ursula(Teacher, Character, Worker):
#
# Self-Ursula
#
if is_me is True: # TODO: 340
# TODO: Better handle ephemeral staking self ursula <-- Is this still relevant?
if is_me is True: # TODO: #340
self._stored_treasure_maps = dict()
#
@ -892,13 +894,11 @@ class Ursula(Teacher, Character, Worker):
stake_tracker=stake_tracker)
# Access to worker's ETH client via node's transacting keys
# TODO: Better handle ephemeral staking self ursula <-- Is this still relevant?
blockchain_power = BlockchainPower(client=self.blockchain.client)
# TODO: #1092 - TransactingPower
blockchain_power = BlockchainPower(blockchain=self.blockchain, account=worker_address)
self._crypto_power.consume_power_up(blockchain_power)
# TODO: #1092
# Use blockchain power to substantiate stamp
self.substantiate_stamp(client_password=password, checksum_address=worker_address) # TODO: Derive from keyring
self.blockchain.transacting_power = blockchain_power # TODO: Embed in powerups
self.substantiate_stamp(client_password=password) # TODO: Use PowerUp / Derive from keyring
#
# ProxyRESTServer and TLSHostingPower # TODO: Maybe we want _power_ups to be public after all?

View File

@ -108,9 +108,6 @@ def deploy(click_config,
fetch_registry=False,
sync_now=sync)
# TODO: Integrate with Deployer Actor (Character)
blockchain.transacting_power = BlockchainPower(client=blockchain.client)
#
# Deployment Actor
#
@ -125,6 +122,9 @@ def deploy(click_config,
# Verify Address
if not force:
click.confirm("Selected {} - Continue?".format(deployer_address), abort=True)
# TODO: Integrate with Deployer Actor (Character)
blockchain.transacting_power = BlockchainPower(blockchain=blockchain, account=deployer_address)
deployer = Deployer(blockchain=blockchain, deployer_address=deployer_address)
# Verify ETH Balance

View File

@ -92,39 +92,44 @@ class BlockchainPower(CryptoPowerUp):
"""
not_found_error = NoBlockchainPower
def __init__(self, client=None, device=None) -> None:
def __init__(self, blockchain: 'Blockchain', account: str, device = None) -> None:
"""
Instantiates a BlockchainPower for the given account id.
"""
self.blockchain = blockchain
self.account = account
self.device = device
self.client = client
self.is_unlocked = False
def unlock_account(self, account, password: str):
def unlock_account(self, password: str):
"""
Unlocks the account for the specified duration. If no duration is
provided, it will remain unlocked indefinitely.
"""
self.is_unlocked = self.client.unlock_account(account, password)
self.is_unlocked = self.blockchain.client.unlock_account(self.account, password)
if not self.is_unlocked:
raise PowerUpError("Failed to unlock account {}".format(account))
raise PowerUpError("Failed to unlock account {}".format(self.account))
def sign_message(self, message: bytes, account: str) -> bytes:
def sign_message(self, message: bytes) -> bytes:
"""
Signs the message with the private key of the BlockchainPower.
"""
if not self.is_unlocked:
raise PowerUpError("Account is not unlocked.")
signature = self.client.sign_message(account, message)
signature = self.blockchain.client.sign_message(account=self.account, message=message)
return signature
def sign_transaction(self, unsigned_transaction: dict, sender_address: str):
def sign_transaction(self, unsigned_transaction: dict):
if self.device:
assert False
elif self.client:
signed_raw_transaction = self.client.sign_transaction(transaction=unsigned_transaction,
account=sender_address)
return signed_raw_transaction
# TODO: Implement TrustedDevice
raise NotImplementedError
sender_address = unsigned_transaction['from']
if sender_address != self.account:
raise PowerUpError(f"'from' field must match key's {self.account}, but it was {sender_address}")
signed_transaction = self.blockchain.client.sign_transaction(transaction=unsigned_transaction, account=self.account)
return signed_transaction
class KeyPairBasedPower(CryptoPowerUp):

View File

@ -913,7 +913,8 @@ class Teacher:
self.__worker_address = None
if substantiate_immediately:
self.substantiate_stamp(client_password=password, checksum_address=worker_address)
# TODO: #1091
self.substantiate_stamp(client_password=password)
class InvalidNode(SuspiciousActivity):
"""Raised when a node has an invalid characteristic - stamp, interface, or address."""
@ -1146,12 +1147,13 @@ class Teacher:
signature=self.decentralized_identity_evidence)
return self.__worker_address
def substantiate_stamp(self, client_password: str, checksum_address: str):
def substantiate_stamp(self, client_password: str):
# TODO: #1092 - TransactingPower
blockchain_power = self._crypto_power.power_ups(BlockchainPower)
blockchain_power.unlock_account(password=client_password, account=checksum_address) # TODO: #349
signature = blockchain_power.sign_message(message=bytes(self.stamp), account=checksum_address)
blockchain_power.unlock_account(password=client_password) # TODO: #349
signature = blockchain_power.sign_message(message=bytes(self.stamp))
self.__decentralized_identity_evidence = signature
self.__worker_address = checksum_address
self.__worker_address = blockchain_power.account
#
# Interface

View File

@ -212,8 +212,8 @@ class TesterBlockchain(BlockchainDeployerInterface):
"""For use with metric testing scripts"""
testerchain = cls(compiler=SolidityCompiler())
power = BlockchainPower(client=testerchain.client)
power.unlock_account(account=testerchain.client.etherbase, password=INSECURE_DEVELOPMENT_PASSWORD)
power = BlockchainPower(blockchain=testerchain, account=testerchain.client.etherbase)
power.unlock_account(password=INSECURE_DEVELOPMENT_PASSWORD)
testerchain.transacting_power = power
origin = testerchain.client.etherbase

View File

@ -47,7 +47,8 @@ def test_rapid_deployment(token_economics):
test_accounts=4,
compiler=compiler)
blockchain.transacting_power = BlockchainPower(client=blockchain.client)
# TODO: #1092 - TransactingPower
blockchain.transacting_power = BlockchainPower(blockchain=blockchain, account=blockchain.etherbase_account)
deployer_address = blockchain.etherbase_account
deployer = Deployer(blockchain=blockchain, deployer_address=deployer_address)

View File

@ -123,7 +123,7 @@ def test_character_blockchain_power(testerchain, agency):
sig_privkey = testerchain.provider.ethereum_tester.backend._key_lookup[canonical_address]
signer = Character(is_me=True, blockchain=testerchain, checksum_address=eth_address)
signer._crypto_power.consume_power_up(BlockchainPower(testerchain.client, eth_address))
signer._crypto_power.consume_power_up(BlockchainPower(blockchain=testerchain, account=eth_address))
# Due to testing backend, the account is already unlocked.
power = signer._crypto_power.power_ups(BlockchainPower)
@ -131,7 +131,7 @@ def test_character_blockchain_power(testerchain, agency):
# power.unlock_account('this-is-not-a-secure-password')
data_to_sign = b'What does Ursula look like?!?'
sig = power.sign_message(message=data_to_sign, account=eth_address)
sig = power.sign_message(message=data_to_sign)
is_verified = verify_eip_191(address=eth_address, message=data_to_sign, signature=sig)
assert is_verified is True
@ -145,7 +145,7 @@ def test_character_blockchain_power(testerchain, agency):
# Test a signature without unlocking the account
power.is_unlocked = False
with pytest.raises(PowerUpError):
power.sign_message(message=b'test', account=eth_address)
power.sign_message(message=b'test')
# Test lockAccount call
del power

View File

@ -44,7 +44,7 @@ def make_testerchain():
# Set the deployer address from a freshly created test account
testerchain.deployer_address = testerchain.etherbase_account
testerchain.transacting_power = BlockchainPower(client=testerchain.client)
testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=testerchain.etherbase_account)
return testerchain

View File

@ -370,7 +370,10 @@ def testerchain():
"""
# Create the blockchain
testerchain = TesterBlockchain(eth_airdrop=True, free_transactions=True)
testerchain.transacting_power = BlockchainPower(client=testerchain.client)
# TODO: TransactingPower
# Mock TransactingPower Consumption
testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=testerchain.etherbase_account)
testerchain.deployer_address = testerchain.etherbase_account
yield testerchain
testerchain.disconnect()
@ -426,6 +429,10 @@ def stakers(agency, token_economics):
for index, account in enumerate(blockchain.stakers_accounts):
staker = Staker(is_me=True, checksum_address=account, blockchain=blockchain)
# TODO: #1092 - TransactingPower
# Mock TransactingPower consumption
staker.blockchain.transacting_power = BlockchainPower(blockchain=staker.blockchain, account=staker.checksum_address)
min_stake, balance = token_economics.minimum_allowed_locked, staker.token_balance
amount = random.randint(min_stake, balance)