nucypher/tests/metrics/estimate_gas.py

580 lines
25 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""
This file is part of nucypher.
nucypher is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
nucypher is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
import json
import os
import sys
2019-08-01 12:54:12 +00:00
import io
import re
import tabulate
import time
from os.path import abspath, dirname
from unittest.mock import Mock
from twisted.logger import globalLogPublisher, Logger, jsonFileLogObserver, ILogObserver
from zope.interface import provider
2019-06-15 16:51:06 +00:00
from nucypher.blockchain.economics import StandardTokenEconomics
2019-07-10 09:46:58 +00:00
from nucypher.blockchain.eth.agents import NucypherTokenAgent, StakingEscrowAgent, PolicyManagerAgent, AdjudicatorAgent
from nucypher.blockchain.eth.constants import NUCYPHER_CONTRACT_NAMES
from nucypher.crypto.signing import SignatureStamp
from nucypher.policy.policies import Policy
from nucypher.utilities.sandbox.blockchain import TesterBlockchain
2019-08-01 12:54:12 +00:00
from umbral.keys import UmbralPrivateKey
from umbral.signing import Signer
# FIXME: Needed to use a fixture here, but now estimate_gas.py only runs if executed from main directory
sys.path.insert(0, abspath('tests'))
from fixtures import _mock_ursula_reencrypts as mock_ursula_reencrypts
ALGORITHM_SHA256 = 1
2019-06-15 16:51:06 +00:00
TOKEN_ECONOMICS = StandardTokenEconomics()
MIN_ALLOWED_LOCKED = TOKEN_ECONOMICS.minimum_allowed_locked
MIN_LOCKED_PERIODS = TOKEN_ECONOMICS.minimum_locked_periods
MAX_ALLOWED_LOCKED = TOKEN_ECONOMICS.maximum_allowed_locked
2019-06-15 16:51:06 +00:00
MAX_MINTING_PERIODS = TOKEN_ECONOMICS.maximum_rewarded_periods
class AnalyzeGas:
"""
Callable twisted log observer with built-in record-keeping for gas estimation runs.
"""
# Logging
LOG_NAME = 'estimate-gas'
LOG_FILENAME = '{}.log.json'.format(LOG_NAME)
OUTPUT_DIR = os.path.join(abspath(dirname(__file__)), 'results')
JSON_OUTPUT_FILENAME = '{}.json'.format(LOG_NAME)
_PATTERN = re.compile(r'''
^ # Anchor at the start of a string
(.+) # Any character sequence longer than 1; Captured
\s=\s # Space-Equal-Space
(\d+) # A sequence of digits; Captured
\s\|\s # Space-Slash-Space
2019-07-26 12:40:30 +00:00
(\d+) # A sequence of digits; Captured
$ # Anchor at the end of the string
''', re.VERBOSE)
def __init__(self) -> None:
self.log = Logger(self.__class__.__name__)
self.gas_estimations = dict()
if not os.path.isdir(self.OUTPUT_DIR):
os.mkdir(self.OUTPUT_DIR)
@provider(ILogObserver)
def __call__(self, event, *args, **kwargs) -> None:
if event.get('log_namespace') == self.LOG_NAME:
message = event.get("log_format")
matches = self._PATTERN.match(message)
if not matches:
self.log.debug("No match for {} with pattern {}".format(message, self._PATTERN))
return
2019-07-26 12:40:30 +00:00
label, estimates, gas_used = matches.groups()
self.paint_line(label, estimates, gas_used)
self.gas_estimations[label] = int(gas_used)
@staticmethod
2019-07-26 12:40:30 +00:00
def paint_line(label: str, estimates: str, gas_used: str) -> None:
print('{label} {estimates:7,} | {gas:7,}'.format(
label=label.ljust(72, '.'), estimates=int(estimates), gas=int(gas_used)))
def to_json_file(self) -> None:
print('Saving JSON Output...')
2018-06-15 05:51:28 +00:00
epoch_time = str(int(time.time()))
timestamped_filename = '{}-{}'.format(epoch_time, self.JSON_OUTPUT_FILENAME)
filepath = os.path.join(self.OUTPUT_DIR, timestamped_filename)
with open(filepath, 'w') as file:
file.write(json.dumps(self.gas_estimations, indent=4))
2018-06-15 05:51:28 +00:00
def start_collection(self) -> None:
print("Starting Data Collection...")
json_filepath = os.path.join(self.OUTPUT_DIR, AnalyzeGas.LOG_FILENAME)
json_io = io.open(json_filepath, "w")
json_observer = jsonFileLogObserver(json_io)
globalLogPublisher.addObserver(json_observer)
globalLogPublisher.addObserver(self)
2018-06-15 05:51:28 +00:00
def mock_ursula(testerchain, account):
ursula_privkey = UmbralPrivateKey.gen_key()
ursula_stamp = SignatureStamp(verifying_key=ursula_privkey.pubkey,
signer=Signer(ursula_privkey))
signed_stamp = testerchain.client.sign_message(account=account,
message=bytes(ursula_stamp))
ursula = Mock(stamp=ursula_stamp, decentralized_identity_evidence=signed_stamp)
return ursula
def generate_args_for_slashing(ursula, corrupt_cfrag: bool = True):
evidence = mock_ursula_reencrypts(ursula, corrupt_cfrag=corrupt_cfrag)
args = list(evidence.evaluation_arguments())
return args
def estimate_gas(analyzer: AnalyzeGas = None) -> None:
"""
Execute a linear sequence of NyCypher transactions mimicking
post-deployment usage on a local PyEVM blockchain;
Record the resulting estimated transaction gas expenditure.
Note: The function calls below are *order dependant*
"""
#
# Setup
#
2018-12-18 18:31:41 +00:00
if analyzer is None:
analyzer = AnalyzeGas()
log = Logger(AnalyzeGas.LOG_NAME)
2019-07-26 12:40:30 +00:00
os.environ['GAS_ESTIMATOR_BACKEND_FUNC'] = 'eth.estimators.gas.binary_gas_search_exact'
# Blockchain
2019-07-12 10:15:28 +00:00
economics = StandardTokenEconomics(
base_penalty=MIN_ALLOWED_LOCKED - 1,
penalty_history_coefficient=0,
percentage_penalty_coefficient=2,
reward_coefficient=2
)
testerchain, registry = TesterBlockchain.bootstrap_network(economics=economics)
web3 = testerchain.w3
print("\n********* SIZE OF MAIN CONTRACTS *********")
MAX_SIZE = 24576
rows = list()
for contract_name in NUCYPHER_CONTRACT_NAMES:
compiled_contract = testerchain._raw_contract_cache[contract_name]
version = list(compiled_contract).pop()
bin_runtime = compiled_contract[version]['bin-runtime']
bin_length_in_bytes = len(bin_runtime) // 2
percentage = int(100 * bin_length_in_bytes / MAX_SIZE)
bar = ('*'*(percentage//2)).ljust(50)
rows.append((contract_name, bin_length_in_bytes, f'{bar} {percentage}%'))
headers = ('Contract', 'Size (B)', f'% of max allowed contract size ({MAX_SIZE} B)')
print(tabulate.tabulate(rows, headers=headers, tablefmt="simple"), end="\n\n")
# Accounts
origin, ursula1, ursula2, ursula3, alice1, alice2, *everyone_else = testerchain.client.accounts
ursula_with_stamp = mock_ursula(testerchain, ursula1)
# Contracts
token_agent = NucypherTokenAgent(registry=registry)
staking_agent = StakingEscrowAgent(registry=registry)
policy_agent = PolicyManagerAgent(registry=registry)
adjudicator_agent = AdjudicatorAgent(registry=registry)
# Contract Callers
token_functions = token_agent.contract.functions
staker_functions = staking_agent.contract.functions
policy_functions = policy_agent.contract.functions
adjudicator_functions = adjudicator_agent.contract.functions
analyzer.start_collection()
print("********* Estimating Gas *********")
2018-06-15 05:51:28 +00:00
2019-07-26 12:40:30 +00:00
def transact_and_log(label, function, transaction):
estimates = function.estimateGas(transaction)
transaction.update(gas=estimates)
tx = function.transact(transaction)
receipt = testerchain.wait_for_receipt(tx)
log.info(f"{label} = {estimates} | {receipt['gasUsed']}")
2019-07-26 12:40:30 +00:00
def transact(function, transaction):
2019-08-01 12:54:12 +00:00
transaction.update(gas=1000000)
2019-07-26 12:40:30 +00:00
tx = function.transact(transaction)
testerchain.wait_for_receipt(tx)
#
# Give Ursula and Alice some coins
#
2019-07-26 12:40:30 +00:00
transact_and_log("Transfer tokens", token_functions.transfer(ursula1, MIN_ALLOWED_LOCKED * 10), {'from': origin})
transact(token_functions.transfer(ursula2, MIN_ALLOWED_LOCKED * 10), {'from': origin})
transact(token_functions.transfer(ursula3, MIN_ALLOWED_LOCKED * 10), {'from': origin})
#
# Ursula and Alice give Escrow rights to transfer
#
transact_and_log("Approving transfer",
token_functions.approve(staking_agent.contract_address, MIN_ALLOWED_LOCKED * 6),
{'from': ursula1})
transact(token_functions.approve(staking_agent.contract_address, MIN_ALLOWED_LOCKED * 6), {'from': ursula2})
transact(token_functions.approve(staking_agent.contract_address, MIN_ALLOWED_LOCKED * 6), {'from': ursula3})
#
# Batch deposit tokens
#
transact(token_functions.approve(staking_agent.contract_address, MIN_ALLOWED_LOCKED * 10), {'from': origin})
transact_and_log("Batch deposit tokens for 5 owners x 2 sub-stakes",
staker_functions.batchDeposit(everyone_else[0:5],
[2] * 5,
[MIN_ALLOWED_LOCKED] * 10,
[MIN_LOCKED_PERIODS] * 10),
{'from': origin})
transact(token_functions.approve(staking_agent.contract_address, MIN_ALLOWED_LOCKED * 24), {'from': origin})
transact_and_log("Batch deposit tokens for 1 owners x 24 sub-stakes",
staker_functions.batchDeposit([everyone_else[6]],
[24],
[MIN_ALLOWED_LOCKED] * 24,
[MIN_LOCKED_PERIODS] * 24),
{'from': origin})
transact(token_functions.approve(staking_agent.contract_address, MIN_ALLOWED_LOCKED * 24 * 5), {'from': origin})
transact_and_log("Batch deposit tokens for 5 owners x 24 sub-stakes",
staker_functions.batchDeposit(everyone_else[7:12],
[24]*5,
[MIN_ALLOWED_LOCKED] * (24 * 5),
[MIN_LOCKED_PERIODS] * (24 * 5)),
{'from': origin})
#
# Ursula and Alice transfer some tokens to the escrow and lock them
#
transact_and_log("Initial deposit tokens, first",
2019-07-26 12:40:30 +00:00
staker_functions.deposit(MIN_ALLOWED_LOCKED * 3, MIN_LOCKED_PERIODS),
{'from': ursula1})
transact_and_log("Initial deposit tokens, other",
2019-07-26 12:40:30 +00:00
staker_functions.deposit(MIN_ALLOWED_LOCKED * 3, MIN_LOCKED_PERIODS),
{'from': ursula2})
transact(staker_functions.deposit(MIN_ALLOWED_LOCKED * 3, MIN_LOCKED_PERIODS), {'from': ursula3})
transact(staker_functions.setWorker(ursula1), {'from': ursula1})
transact(staker_functions.setWorker(ursula2), {'from': ursula2})
transact(staker_functions.setWorker(ursula3), {'from': ursula3})
transact(staker_functions.setReStake(False), {'from': ursula1})
transact(staker_functions.setReStake(False), {'from': ursula2})
transact(staker_functions.setWindDown(True), {'from': ursula1})
transact(staker_functions.setWindDown(True), {'from': ursula2})
2019-07-26 12:40:30 +00:00
transact(staker_functions.confirmActivity(), {'from': ursula1})
transact(staker_functions.confirmActivity(), {'from': ursula2})
#
# Wait 1 period and confirm activity
#
2018-06-15 05:51:28 +00:00
testerchain.time_travel(periods=1)
transact_and_log("Confirm activity, first", staker_functions.confirmActivity(), {'from': ursula1})
transact_and_log("Confirm activity, other", staker_functions.confirmActivity(), {'from': ursula2})
#
# Wait 1 period and mint tokens
#
2018-06-15 05:51:28 +00:00
testerchain.time_travel(periods=1)
transact_and_log("Minting (1 stake), first", staker_functions.mint(), {'from': ursula1})
transact_and_log("Minting (1 stake), other", staker_functions.mint(), {'from': ursula2})
transact_and_log("Confirm activity again, first", staker_functions.confirmActivity(), {'from': ursula1})
transact_and_log("Confirm activity again, other", staker_functions.confirmActivity(), {'from': ursula2})
transact(staker_functions.confirmActivity(), {'from': ursula3})
#
# Confirm again
#
2018-06-15 05:51:28 +00:00
testerchain.time_travel(periods=1)
transact_and_log("Confirm activity + mint, first", staker_functions.confirmActivity(), {'from': ursula1})
transact_and_log("Confirm activity + mint, other", staker_functions.confirmActivity(), {'from': ursula2})
#
# Create policy
#
policy_id_1 = os.urandom(int(Policy.POLICY_ID_LENGTH))
policy_id_2 = os.urandom(int(Policy.POLICY_ID_LENGTH))
number_of_periods = 10
rate = 100
one_period = economics.hours_per_period * 60 * 60
value = number_of_periods * rate
current_timestamp = testerchain.w3.eth.getBlock(block_identifier='latest').timestamp
end_timestamp = current_timestamp + (number_of_periods - 1) * one_period
transact_and_log("Creating policy (1 node, 10 periods, pre-confirmed), first",
policy_functions.createPolicy(policy_id_1, alice1, end_timestamp, [ursula1]),
{'from': alice1, 'value': value})
transact_and_log("Creating policy (1 node, 10 periods, pre-confirmed), other",
policy_functions.createPolicy(policy_id_2, alice1, end_timestamp, [ursula1]),
{'from': alice1, 'value': value})
#
# Get locked tokens
#
2019-07-26 12:40:30 +00:00
transact_and_log("Getting locked tokens", staker_functions.getLockedTokens(ursula1, 0), {})
#
# Wait 1 period and withdraw tokens
#
2018-06-15 05:51:28 +00:00
testerchain.time_travel(periods=1)
2019-07-26 12:40:30 +00:00
transact_and_log("Withdraw", staker_functions.withdraw(1), {'from': ursula1})
#
2019-03-10 14:33:33 +00:00
# Confirm activity with re-stake
#
2019-07-26 12:40:30 +00:00
transact(staker_functions.setReStake(True), {'from': ursula1})
transact(staker_functions.setReStake(True), {'from': ursula2})
# Used to remove spending for first call in a day for mint and confirmActivity
transact(staker_functions.confirmActivity(), {'from': ursula3})
transact_and_log("Confirm activity + mint + re-stake",
2019-07-26 12:40:30 +00:00
staker_functions.confirmActivity(),
{'from': ursula2})
2020-05-06 14:32:12 +00:00
transact_and_log("Confirm activity + mint + re-stake + first fee + first fee rate",
staker_functions.confirmActivity(),
{'from': ursula1})
2019-07-26 12:40:30 +00:00
transact(staker_functions.setReStake(False), {'from': ursula1})
transact(staker_functions.setReStake(False), {'from': ursula2})
2019-03-10 14:33:33 +00:00
#
# Wait 2 periods and confirm activity after downtime
#
testerchain.time_travel(periods=2)
transact(staker_functions.confirmActivity(), {'from': ursula3})
transact_and_log("Confirm activity after downtime", staker_functions.confirmActivity(), {'from': ursula2})
2020-05-06 14:32:12 +00:00
transact_and_log("Confirm activity after downtime + updating fee",
staker_functions.confirmActivity(),
{'from': ursula1})
#
# Ursula and Alice deposit some tokens to the escrow again
#
2019-07-26 12:40:30 +00:00
transact_and_log("Deposit tokens after confirming activity",
staker_functions.deposit(MIN_ALLOWED_LOCKED * 2, MIN_LOCKED_PERIODS),
{'from': ursula1})
transact(staker_functions.deposit(MIN_ALLOWED_LOCKED * 2, MIN_LOCKED_PERIODS), {'from': ursula2})
#
# Revoke policy
#
transact_and_log("Revoking policy", policy_functions.revokePolicy(policy_id_1), {'from': alice1})
#
# Wait 1 period
#
testerchain.time_travel(periods=1)
#
# Create policy with multiple pre-confirmed nodes
#
policy_id_1 = os.urandom(int(Policy.POLICY_ID_LENGTH))
policy_id_2 = os.urandom(int(Policy.POLICY_ID_LENGTH))
policy_id_3 = os.urandom(int(Policy.POLICY_ID_LENGTH))
number_of_periods = 100
value = 3 * number_of_periods * rate
current_timestamp = testerchain.w3.eth.getBlock(block_identifier='latest').timestamp
end_timestamp = current_timestamp + (number_of_periods - 1) * one_period
transact_and_log("Creating policy (3 nodes, 100 periods, pre-confirmed), first",
policy_functions.createPolicy(policy_id_1, alice1, end_timestamp, [ursula1, ursula2, ursula3]),
2019-07-26 12:40:30 +00:00
{'from': alice1, 'value': value})
transact_and_log("Creating policy (3 nodes, 100 periods, pre-confirmed), other",
policy_functions.createPolicy(policy_id_2, alice1, end_timestamp, [ursula1, ursula2, ursula3]),
{'from': alice1, 'value': value})
value = 2 * number_of_periods * rate
transact_and_log("Creating policy (2 nodes, 100 periods, pre-confirmed), other",
policy_functions.createPolicy(policy_id_3, alice1, end_timestamp, [ursula1, ursula2]),
2019-07-26 12:40:30 +00:00
{'from': alice1, 'value': value})
#
# Wait 1 period and mint tokens
#
testerchain.time_travel(periods=1)
transact(staker_functions.mint(), {'from': ursula3})
transact_and_log("Last minting + updating fee + updating fee rate", staker_functions.mint(), {'from': ursula1})
transact_and_log("Last minting + first fee + first fee rate", staker_functions.mint(), {'from': ursula2})
#
# Create policy again without pre-confirmed nodes
#
policy_id_1 = os.urandom(int(Policy.POLICY_ID_LENGTH))
policy_id_2 = os.urandom(int(Policy.POLICY_ID_LENGTH))
policy_id_3 = os.urandom(int(Policy.POLICY_ID_LENGTH))
number_of_periods = 100
value = number_of_periods * rate
current_timestamp = testerchain.w3.eth.getBlock(block_identifier='latest').timestamp
end_timestamp = current_timestamp + (number_of_periods - 1) * one_period
transact_and_log("Creating policy (1 node, 100 periods)",
policy_functions.createPolicy(policy_id_1, alice2, end_timestamp, [ursula2]),
2019-07-26 12:40:30 +00:00
{'from': alice1, 'value': value})
2018-06-15 05:51:28 +00:00
testerchain.time_travel(periods=1)
current_timestamp = testerchain.w3.eth.getBlock(block_identifier='latest').timestamp
end_timestamp = current_timestamp + (number_of_periods - 1) * one_period
transact_and_log("Creating policy (1 node, 100 periods), next period",
policy_functions.createPolicy(policy_id_2, alice2, end_timestamp, [ursula2]),
2019-07-26 12:40:30 +00:00
{'from': alice1, 'value': value})
transact_and_log("Creating policy (1 node, 100 periods), another node",
policy_functions.createPolicy(policy_id_3, alice2, end_timestamp, [ursula1]),
2019-07-26 12:40:30 +00:00
{'from': alice1, 'value': value})
#
# Mint and revoke policy
#
2018-06-15 05:51:28 +00:00
testerchain.time_travel(periods=10)
2019-07-26 12:40:30 +00:00
transact(staker_functions.confirmActivity(), {'from': ursula1})
transact(staker_functions.confirmActivity(), {'from': ursula3})
2018-06-15 05:51:28 +00:00
2019-07-26 12:40:30 +00:00
testerchain.time_travel(periods=2)
transact(staker_functions.mint(), {'from': ursula3})
transact_and_log("Last minting after downtime + updating fee",
staker_functions.mint(),
{'from': ursula1})
2018-06-15 05:51:28 +00:00
testerchain.time_travel(periods=10)
transact_and_log("Revoking policy after downtime, 1st policy",
2019-07-26 12:40:30 +00:00
policy_functions.revokePolicy(policy_id_1),
{'from': alice2})
transact_and_log("Revoking policy after downtime, 2nd policy",
2019-07-26 12:40:30 +00:00
policy_functions.revokePolicy(policy_id_2),
{'from': alice2})
transact_and_log("Revoking policy after downtime, 3rd policy",
2019-07-26 12:40:30 +00:00
policy_functions.revokePolicy(policy_id_3),
{'from': alice2})
2018-06-15 05:51:28 +00:00
for index in range(5):
2019-07-26 12:40:30 +00:00
transact(staker_functions.confirmActivity(), {'from': ursula1})
2018-06-15 05:51:28 +00:00
testerchain.time_travel(periods=1)
2019-07-26 12:40:30 +00:00
transact(staker_functions.mint(), {'from': ursula1})
2018-06-15 05:51:28 +00:00
#
2018-06-15 05:51:28 +00:00
# Check regular deposit
#
2019-07-26 12:40:30 +00:00
transact_and_log("Deposit tokens",
staker_functions.deposit(MIN_ALLOWED_LOCKED, MIN_LOCKED_PERIODS),
{'from': ursula1})
2018-06-15 05:51:28 +00:00
#
2018-06-15 05:51:28 +00:00
# ApproveAndCall
#
2018-06-15 05:51:28 +00:00
testerchain.time_travel(periods=1)
2019-07-26 12:40:30 +00:00
transact(staker_functions.mint(), {'from': ursula1})
2018-06-15 05:51:28 +00:00
2019-07-26 12:40:30 +00:00
transact_and_log("ApproveAndCall",
token_functions.approveAndCall(staking_agent.contract_address,
MIN_ALLOWED_LOCKED * 2,
web3.toBytes(MIN_LOCKED_PERIODS)),
{'from': ursula1})
2018-06-15 05:51:28 +00:00
#
2018-06-15 05:51:28 +00:00
# Locking tokens
#
2018-06-15 05:51:28 +00:00
testerchain.time_travel(periods=1)
2019-07-26 12:40:30 +00:00
transact(staker_functions.confirmActivity(), {'from': ursula1})
transact_and_log("Locking tokens", staker_functions.lock(MIN_ALLOWED_LOCKED, MIN_LOCKED_PERIODS), {'from': ursula1})
2018-06-15 05:51:28 +00:00
#
2018-06-15 05:51:28 +00:00
# Divide stake
#
2019-07-26 12:40:30 +00:00
transact_and_log("Divide stake", staker_functions.divideStake(1, MIN_ALLOWED_LOCKED, 2), {'from': ursula1})
transact(staker_functions.divideStake(3, MIN_ALLOWED_LOCKED, 2), {'from': ursula1})
2018-06-15 05:51:28 +00:00
#
2018-06-15 05:51:28 +00:00
# Divide almost finished stake
#
2018-06-15 05:51:28 +00:00
testerchain.time_travel(periods=1)
2019-07-26 12:40:30 +00:00
transact(staker_functions.confirmActivity(), {'from': ursula1})
2018-06-15 05:51:28 +00:00
testerchain.time_travel(periods=1)
2019-07-26 12:40:30 +00:00
transact(staker_functions.confirmActivity(), {'from': ursula1})
2019-03-10 14:33:33 +00:00
#
# Slashing tests
2019-03-10 14:33:33 +00:00
#
2019-07-26 12:40:30 +00:00
transact(staker_functions.confirmActivity(), {'from': ursula1})
testerchain.time_travel(periods=1)
2019-03-10 14:33:33 +00:00
#
# Slashing
2019-03-10 14:33:33 +00:00
#
slashing_args = generate_args_for_slashing(ursula_with_stamp)
2019-07-26 12:40:30 +00:00
transact_and_log("Slash just value", adjudicator_functions.evaluateCFrag(*slashing_args), {'from': alice1})
deposit = staker_functions.stakerInfo(ursula1).call()[0]
unlocked = deposit - staker_functions.getLockedTokens(ursula1, 0).call()
2019-07-26 12:40:30 +00:00
transact(staker_functions.withdraw(unlocked), {'from': ursula1})
sub_stakes_length = str(staker_functions.getSubStakesLength(ursula1).call())
slashing_args = generate_args_for_slashing(ursula_with_stamp)
2019-07-26 12:40:30 +00:00
transact_and_log("Slashing one sub stake and saving old one (" + sub_stakes_length + " sub stakes), 1st",
adjudicator_functions.evaluateCFrag(*slashing_args),
{'from': alice1})
sub_stakes_length = str(staker_functions.getSubStakesLength(ursula1).call())
slashing_args = generate_args_for_slashing(ursula_with_stamp)
2019-07-26 12:40:30 +00:00
transact_and_log("Slashing one sub stake and saving old one (" + sub_stakes_length + " sub stakes), 2nd",
adjudicator_functions.evaluateCFrag(*slashing_args),
{'from': alice1})
sub_stakes_length = str(staker_functions.getSubStakesLength(ursula1).call())
slashing_args = generate_args_for_slashing(ursula_with_stamp)
2019-07-26 12:40:30 +00:00
transact_and_log("Slashing one sub stake and saving old one (" + sub_stakes_length + " sub stakes), 3rd",
adjudicator_functions.evaluateCFrag(*slashing_args),
{'from': alice1})
sub_stakes_length = str(staker_functions.getSubStakesLength(ursula1).call())
slashing_args = generate_args_for_slashing(ursula_with_stamp)
2019-07-26 12:40:30 +00:00
transact_and_log("Slashing two sub stakes and saving old one (" + sub_stakes_length + " sub stakes)",
adjudicator_functions.evaluateCFrag(*slashing_args),
{'from': alice1})
for index in range(18):
2019-07-26 12:40:30 +00:00
transact(staker_functions.confirmActivity(), {'from': ursula1})
testerchain.time_travel(periods=1)
2019-07-26 12:40:30 +00:00
transact(staker_functions.lock(MIN_ALLOWED_LOCKED, MIN_LOCKED_PERIODS), {'from': ursula1})
deposit = staker_functions.stakerInfo(ursula1).call()[0]
unlocked = deposit - staker_functions.getLockedTokens(ursula1, 1).call()
2019-07-26 12:40:30 +00:00
transact(staker_functions.withdraw(unlocked), {'from': ursula1})
sub_stakes_length = str(staker_functions.getSubStakesLength(ursula1).call())
slashing_args = generate_args_for_slashing(ursula_with_stamp)
2019-07-26 12:40:30 +00:00
transact_and_log("Slashing two sub stakes, shortest and new one (" + sub_stakes_length + " sub stakes)",
adjudicator_functions.evaluateCFrag(*slashing_args),
{'from': alice1})
sub_stakes_length = str(staker_functions.getSubStakesLength(ursula1).call())
slashing_args = generate_args_for_slashing(ursula_with_stamp)
2019-07-26 12:40:30 +00:00
transact_and_log("Slashing three sub stakes, two shortest and new one (" + sub_stakes_length + " sub stakes)",
adjudicator_functions.evaluateCFrag(*slashing_args),
{'from': alice1})
slashing_args = generate_args_for_slashing(ursula_with_stamp, corrupt_cfrag=False)
2019-07-26 12:40:30 +00:00
transact_and_log("Evaluating correct CFrag", adjudicator_functions.evaluateCFrag(*slashing_args), {'from': alice1})
transact_and_log("Prolong stake", staker_functions.prolongStake(0, 20), {'from': ursula1})
print("********* All Done! *********")
if __name__ == "__main__":
print("Starting Up...")
analyzer = AnalyzeGas()
estimate_gas(analyzer=analyzer)
analyzer.to_json_file()