Merge pull request #1582 from KPrasch/felix

Felix Update and Staging
pull/1617/head
K Prasch 2020-01-23 12:28:03 -08:00 committed by GitHub
commit 92b5970e34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 26 deletions

View File

@ -8,7 +8,7 @@ import math
import maya
import time
from constant_sorrow.constants import NOT_RUNNING, NO_DATABASE_AVAILABLE
from flask import Flask, render_template, Response
from flask import Flask, Response
from hendrix.deploy.base import HendrixDeploy
from nacl.hash import sha256
from sqlalchemy import create_engine, or_
@ -46,19 +46,18 @@ class Felix(Character, NucypherTokenActor):
_default_crypto_powerups = [SigningPower]
TEMPLATE_NAME = 'felix.html'
# Intervals
DISTRIBUTION_INTERVAL = 60 # seconds
DISTRIBUTION_INTERVAL = 60 # seconds
DISBURSEMENT_INTERVAL = 24 * 365 # only distribute tokens to the same address once each YEAR.
STAGING_DELAY = 10 # seconds
STAGING_DELAY = 10 # seconds
# Disbursement
BATCH_SIZE = 10 # transactions
MULTIPLIER = Decimal('0.9') # 10% reduction of previous disbursement is 0.9
# this is not relevant until the year of time declared above, passes.
BATCH_SIZE = 10 # transactions
MULTIPLIER = Decimal('0.9') # 10% reduction of previous disbursement is 0.9
# this is not relevant until the year of time declared above, passes.
MINIMUM_DISBURSEMENT = int(1e18) # NuNits (1 NU)
ETHER_AIRDROP_AMOUNT = int(1e17) # Wei (.1 ether)
MAX_INDIVIDUAL_REGISTRATIONS = 3 # Registration Limit
# Node Discovery
LEARNING_TIMEOUT = 30 # seconds
@ -99,8 +98,7 @@ class Felix(Character, NucypherTokenActor):
self.db_engine = create_engine(f'sqlite:///{self.db_filepath}', convert_unicode=True)
# Blockchain
transacting_power = TransactingPower(password=client_password,
account=self.checksum_address)
transacting_power = TransactingPower(password=client_password, account=self.checksum_address, cache=True)
self._crypto_power.consume_power_up(transacting_power)
self.token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=registry)
@ -158,7 +156,7 @@ class Felix(Character, NucypherTokenActor):
__tablename__ = 'recipient'
id = self.db.Column(self.db.Integer, primary_key=True)
address = self.db.Column(self.db.String, unique=True, nullable=False)
address = self.db.Column(self.db.String, nullable=False)
joined = self.db.Column(self.db.DateTime, nullable=False, default=datetime.utcnow)
total_received = self.db.Column(self.db.String, default='0', nullable=False)
last_disbursement_amount = self.db.Column(self.db.String, nullable=False, default=0)
@ -229,10 +227,10 @@ class Felix(Character, NucypherTokenActor):
with ThreadedSession(self.db_engine) as session:
existing = Recipient.query.filter_by(address=new_address).all()
if existing:
if len(existing) > self.MAX_INDIVIDUAL_REGISTRATIONS:
# Address already exists; Abort
self.log.debug(f"{new_address} is already enrolled.")
return Response(response="That address is already enrolled.", status=409)
self.log.debug(f"{new_address} is already enrolled {self.MAX_INDIVIDUAL_REGISTRATIONS} times.")
return Response(response=f"{new_address} requested too many times - Please use another address.", status=409)
# Create the record
recipient = Recipient(address=new_address, joined=datetime.now())
@ -311,6 +309,10 @@ class Felix(Character, NucypherTokenActor):
def __transfer(self, disbursement: int, recipient_address: str) -> str:
"""Perform a single token transfer transaction from one account to another."""
# Re-unlock from cache
self.blockchain.transacting_power.activate()
self.__disbursement += 1
receipt = self.token_agent.transfer(amount=disbursement,
target_address=recipient_address,

View File

@ -5,7 +5,7 @@ from constant_sorrow.constants import NO_BLOCKCHAIN_CONNECTION
from nucypher.characters.banners import FELIX_BANNER
from nucypher.cli import actions, painting
from nucypher.cli.actions import get_nucypher_password, unlock_nucypher_keyring
from nucypher.cli.actions import get_nucypher_password, unlock_nucypher_keyring, get_client_password
from nucypher.cli.config import group_general_config
from nucypher.cli.options import (
group_options,
@ -28,7 +28,7 @@ from nucypher.cli.options import (
)
from nucypher.cli.types import NETWORK_PORT
from nucypher.config.characters import FelixConfiguration
from nucypher.config.constants import DEFAULT_CONFIG_ROOT
from nucypher.config.constants import DEFAULT_CONFIG_ROOT, NUCYPHER_ENVVAR_WORKER_ETH_PASSWORD
option_port = click.option('--port', help="The host port to run Felix HTTP services on", type=NETWORK_PORT, default=FelixConfiguration.DEFAULT_REST_PORT)
@ -71,8 +71,6 @@ class FelixConfigOptions:
rest_port=self.port,
db_filepath=self.db_filepath,
poa=self.poa)
return felix_config
except FileNotFoundError:
return actions.handle_missing_configuration_file(
character_config_class=FelixConfiguration,
@ -129,16 +127,11 @@ class FelixCharacterOptions:
character_configuration=felix_config,
password=get_nucypher_password(confirm=False))
# Produce Teacher Ursulas
teacher_nodes = actions.load_seednodes(emitter,
teacher_uris=self.teacher_uris,
min_stake=self.min_stake,
federated_only=felix_config.federated_only,
network_domains=felix_config.domains,
network_middleware=self.middleware)
client_password = get_client_password(checksum_address=felix_config.checksum_address,
envvar=NUCYPHER_ENVVAR_WORKER_ETH_PASSWORD)
# Produce Felix
FELIX = felix_config.produce(domains=self.config_options.domains, known_nodes=teacher_nodes)
FELIX = felix_config.produce(domains=self.config_options.domains, client_password=client_password)
FELIX.make_web_app() # attach web application, but dont start service
return FELIX

View File

@ -62,6 +62,7 @@ def test_run_felix(click_runner,
# Test subproc (Click)
envvars = {NUCYPHER_ENVVAR_KEYRING_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD,
'NUCYPHER_FELIX_DB_SECRET': INSECURE_DEVELOPMENT_PASSWORD,
'NUCYPHER_WORKER_ETH_PASSWORD': INSECURE_DEVELOPMENT_PASSWORD,
'FLASK_DEBUG': '1'}
# Felix creates a system configuration