Live coding with vicky!

pull/1550/head
Kieran Prasch 2020-01-12 10:59:56 -08:00 committed by Kieran R. Prasch
parent fc45282964
commit b2bf0f487d
5 changed files with 85 additions and 14 deletions

View File

@ -337,6 +337,8 @@ class StandardTokenEconomics(BaseEconomics):
class TestEconomics(StandardTokenEconomics):
# TODO: Move to fixture as instance of base economics
nickname = 'test-economics'
description = f'Identical to {StandardTokenEconomics.nickname} with Instant-start one-hour worklock.'
@ -362,10 +364,6 @@ class TestEconomics(StandardTokenEconomics):
self.worklock_supply = self.maximum_allowed_locked
# TODO: Restore & Move to Standard Economics?
# self.maximum_bid = int(self.maximum_allowed_locked // self.worklock_deposit_rate)
# self.minimum_bid = int(self.minimum_allowed_locked // self.worklock_deposit_rate)
@property
def worklock_deployment_parameters(self):
"""
@ -439,14 +437,14 @@ class EconomicsFactory:
# Worklock
worklock_parameters = worklock_agent.worklock_parameters()
# worklock_supply = worklock_agent.total_supply() # TODO - Need way to read total supply from contract
worklock_supply = worklock_agent.total_supply()
# Aggregate (order-sensitive)
economics_parameters = (initial_supply,
total_supply,
*staking_parameters,
*slashing_parameters,
NotImplemented, # TODO: worklock_supply
worklock_supply,
*worklock_parameters)
economics = BaseEconomics(*economics_parameters)

View File

@ -38,7 +38,8 @@ from nucypher.blockchain.eth.constants import (
)
from nucypher.blockchain.eth.decorators import validate_checksum_address
from nucypher.blockchain.eth.interfaces import BlockchainInterface, BlockchainInterfaceFactory
from nucypher.blockchain.eth.registry import AllocationRegistry, BaseContractRegistry
from nucypher.blockchain.eth.registry import AllocationRegistry, BaseContractRegistry, IndividualAllocationRegistry
from nucypher.blockchain.eth.sol.compile import SolidityCompiler
from nucypher.blockchain.eth.utils import epoch_to_period
from nucypher.crypto.api import sha256_digest
@ -982,6 +983,14 @@ class WorkLockAgent(EthereumContractAgent):
current_bid = self.contract.functions.workInfo(checksum_address).call()[0]
return current_bid
def get_allocation_from_bidder(self, bidder_address: str) -> str:
preallocation_address = self.contract.functions.workInfo(bidder_address).call()[2]
return preallocation_address
def get_token_supply(self) -> int: # TODO: Needs better name
supply = self.contract.functions.tokenSupply().call()
return supply
def cancel_bid(self, sender_address: str) -> dict:
"""
Cancel bid and refund deposited ETH.
@ -991,18 +1000,62 @@ class WorkLockAgent(EthereumContractAgent):
sender_address=sender_address)
return receipt
def _make_preallocation_registry(self, bidder_address: str) -> IndividualAllocationRegistry:
preallocation_address = self.get_allocation_from_bidder(bidder_address=bidder_address)
compiler = SolidityCompiler()
# compiler.install_compiler()
compiled_contracts = compiler.compile()
all_contracts = compiled_contracts[PreallocationEscrowAgent.registry_contract_name]
contract = all_contracts[0] # There is only one version
allocation_registry = IndividualAllocationRegistry(beneficiary_address=bidder_address,
contract_address=preallocation_address,
contract_abi=contract.abi)
return allocation_registry
def get_bidder_from_allocation(self, allocation_address: str) -> str:
bidder = self.contract.functions.depositors(allocation_address).call()
return bidder
def available_refund(self, bidder_address: str = None, allocation_address: str = None) -> int:
# TODO: move up one layer
# TODO: make decorator
if bidder_address and allocation_address:
raise ValueError("Pass bidder address or allocation address, got both.")
if bidder_address:
allocation_address = self.get_allocation_from_bidder(bidder_address=bidder_address)
else:
bidder_address = self.get_bidder_from_allocation(allocation_address=allocation_address)
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=self.registry)
# TODO: Move to agent method
total_completed_work = staking_agent.contracts.functions.getCompletedWork(allocation_address)
refunded_work = self.contract.functions.workInfo(bidder_address).call()[1]
completed_work = total_completed_work - refunded_work
refund_eth = self.contract.functions.workToETH(completed_work).call()
return refund_eth
def claim(self, sender_address: str) -> dict:
"""
Claim tokens - will be deposited and locked as stake in the StakingEscrow contract.
This function produces a new deployment or PreAllocationEscrow for the claimee.
"""
contract_function = self.contract.functions.claim()
receipt = self.blockchain.send_transaction(contract_function=contract_function,
sender_address=sender_address)
return receipt
def burn_unclaimed(self, sender_address: str) -> dict:
"""
Burn unclaimed tokens.
Burn unclaimed tokens -
Out of the goodness of your heart - of course the caller must pay for the gas...
"""
contract_function = self.contract.functions.burnUnclaimed()
receipt = self.blockchain.send_transaction(contract_function=contract_function,

View File

@ -729,6 +729,13 @@ def echo_solidity_version(ctx, param, value):
def paint_worklock_status(emitter, registry: BaseContractRegistry):
"""
# TODO: move some of these to agent?
* depositRate = tokenSupply / ethSupply
* claimedTokens = depositedETH * depositRate
* refundRate = depositRate * SLOWING_REFUND / boostingRefund
* refundETH = completedWork / refundRate
"""
from maya import MayaDT
WORKLOCK_AGENT = ContractAgency.get_agent(WorkLockAgent, registry=registry)
blockchain = WORKLOCK_AGENT.blockchain
@ -742,6 +749,8 @@ def paint_worklock_status(emitter, registry: BaseContractRegistry):
duration = end - start
remaining = end - maya.now()
# TODO: Include calculated refund and deposit rates
payload = f"""
Time
@ -753,9 +762,12 @@ Time Remaining .... {remaining}
Economics
======================================================
Refund Rate ....... {WORKLOCK_AGENT.contract.functions.boostingRefund().call()}
Total Bids ........ {blockchain.client.get_balance(WORKLOCK_AGENT.contract_address)}
Unclaimed Tokens .... {WORKLOCK_AGENT.contract.functions.unclaimedTokens().call()}
Boosting Refund .... {WORKLOCK_AGENT.contract.functions.boostingRefund().call()}
Boosting Refund .... {WORKLOCK_AGENT.contract.functions.boostingRefund().call()}
Total Bids ......... {blockchain.client.get_balance(WORKLOCK_AGENT.contract_address)}
Unclaimed Tokens ... {WORKLOCK_AGENT.contract.functions.unclaimedTokens().call()}
"""
emitter.message(payload)
return

View File

@ -14,13 +14,16 @@ 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 socket
import ssl
import requests
import time
from constant_sorrow.constants import CERTIFICATE_NOT_SAVED, EXEMPT_FROM_VERIFICATION
EXEMPT_FROM_VERIFICATION.bool_value(False)
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from twisted.logger import Logger
@ -30,6 +33,9 @@ from umbral.signing import Signature
from bytestring_splitter import BytestringSplitter, VariableLengthBytestring
EXEMPT_FROM_VERIFICATION.bool_value(False)
class UnexpectedResponse(Exception):
pass
@ -178,8 +184,7 @@ class RestMiddleware:
response = self.client.post(node_or_sprout=node,
path="consider_arrangement",
data=bytes(arrangement),
timeout=2,
)
timeout=2)
return response
def enact_policy(self, ursula, kfrag_id, payload):

View File

@ -71,6 +71,9 @@ def test_status(click_runner, testerchain, test_registry, agency):
result = click_runner.invoke(worklock, command, catch_exceptions=False)
assert result.exit_code == 0
# TODO: Include status for local bidding addresses
# TODO: Eligibility for refund / claim / etc.? - How much redund already dispursed
def test_bid(click_runner, testerchain, test_registry, agency, token_economics):