Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional fix num vaults #75

Merged
merged 1 commit into from
Oct 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Model/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
INVALID_SPEND_RATE = os.getenv("INVALID_SPEND_RATE", None)
# Catastrophe rate per day
CATASTROPHE_RATE = os.getenv("CATASTROPHE_RATE", None)
# Delegate rate per day (if scale_fixed)
DELEGATE_RATE = os.getenv("DELEGATE_RATE", None)

if __name__ == "__main__":
random.seed(21000000)
Expand All @@ -48,12 +50,13 @@
UNVAULT_RATE,
INVALID_SPEND_RATE,
CATASTROPHE_RATE,
DELEGATE_RATE,
]
if any(v is None for v in req_vars):
logging.error(
"Need all these environment variables to be set: N_STK, N_MAN, LOCKTIME,"
" HIST_CSV, RESERVE_STRAT, ESTIMATE_STRAT, I_VERSION,"
" CANCEL_COIN_SELECTION, NUMBER_VAULTS, REFILL_EXCESS,"
" CANCEL_COIN_SELECTION, NUMBER_VAULTS, REFILL_EXCESS, DELEGATE_RATE, "
" REFILL_PERIOD, UNVAULT_RATE, INVALID_SPEND_RATE, CATASTROPHE_RATE."
)
sys.exit(1)
Expand All @@ -73,6 +76,7 @@
float(UNVAULT_RATE),
float(INVALID_SPEND_RATE),
float(CATASTROPHE_RATE),
float(DELEGATE_RATE),
with_balance=True,
# with_fb_coins_dist=True,
with_cum_op_cost=True,
Expand Down
12 changes: 9 additions & 3 deletions Model/results.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ def sim_process(prng_seed, val=None, study_type=None, config_map=None):
"UNVAULT_RATE",
"INVALID_SPEND_RATE",
"CATASTROPHE_RATE",
"DELEGATE_RATE",
"CANCEL_COIN_SELECTION",
]
if study_type not in req_types:
logging.error(
"Study requires a type from: NUMBER_VAULTS,"
" REFILL_EXCESS, REFILL_PERIOD, REFILL_EXCESS, UNVAULT_RATE,"
" REFILL_EXCESS, REFILL_PERIOD, REFILL_EXCESS, UNVAULT_RATE, DELEGATE_RATE"
" INVALID_SPEND_RATE, CATASTROPHE_RATE, N_STK, N_MAN, HIST_CSV,"
" RESERVE_STRAT, ESTIMATE_STRAT, I_VERSION."
" RESERVE_STRAT, ESTIMATE_STRAT, I_VERSION, CANCEL_COIN_SELECTION."
)
sys.exit(1)

Expand All @@ -50,6 +52,8 @@ def sim_process(prng_seed, val=None, study_type=None, config_map=None):
UNVAULT_RATE = {config_map["UNVAULT_RATE"]}
INVALID_SPEND_RATE = {config_map["INVALID_SPEND_RATE"]}
CATASTROPHE_RATE = {config_map["CATASTROPHE_RATE"]}
DELEGATE_RATE = {config_map["DELEGATE_RATE"]}
CANCEL_COIN_SELECTION = {config_map["CANCEL_COIN_SELECTION"]}
"""
)

Expand All @@ -76,6 +80,7 @@ def sim_process(prng_seed, val=None, study_type=None, config_map=None):
int(config_map["UNVAULT_RATE"]),
float(config_map["INVALID_SPEND_RATE"]),
float(config_map["CATASTROPHE_RATE"]),
float(config_map["DELEGATE_RATE"]),
with_balance=True,
with_divergence=True,
with_cum_op_cost=True,
Expand Down Expand Up @@ -126,9 +131,10 @@ def multiprocess_run(range_seed, val, study_type, config_map):
"REFILL_EXCESS": 1,
"UNVAULT_RATE": 1,
"DELEGATE_RATE": 1,
"CANCEL_COIN_SELECTION": 0,
"INVALID_SPEND_RATE": 0.1,
"CATASTROPHE_RATE": 0.005,
"CANCEL_COIN_SELECTION": 0,
"DELEGATE_RATE": 1,
}

# Set the study parameters
Expand Down
65 changes: 40 additions & 25 deletions Model/simulation.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
"""
TODO:
Update sequences to handle transaction broadcast & finalize.
"""

import logging
import random

Expand Down Expand Up @@ -45,6 +40,8 @@ def __init__(
unvault_rate,
invalid_spend_rate,
catastrophe_rate,
delegate_rate,
with_scale_fixed=True,
with_balance=False,
with_divergence=False,
with_op_cost=False,
Expand All @@ -61,6 +58,7 @@ def __init__(
self.refill_excess = refill_excess
self.refill_period = refill_period
self.unvault_rate = unvault_rate
self.delegate_rate = delegate_rate

# Manager parameters
self.invalid_spend_rate = invalid_spend_rate
Expand Down Expand Up @@ -105,6 +103,7 @@ def __init__(
self.fb_coins_dist = []
self.vm_values = []
self.vb_values = []
self.scale_fixed = with_scale_fixed

# Simulation report
self.delegation_failures = 0
Expand Down Expand Up @@ -374,8 +373,8 @@ def confirm_sequence(self, height):
if tx.txouts[-1].processing_state == ProcessingState.UNPROCESSED:
cf_fee = self.wt.broadcast_consolidate_fanout(height)
logging.info(
f" Second Consolidate-fanout transition at block {height} with fee:"
f" {cf_fee}"
f" Second Consolidate-fanout transition at block {height} with"
f" fee: {cf_fee}"
)
if self.cf_fee is None:
self.cf_fee = 0
Expand Down Expand Up @@ -409,27 +408,35 @@ def run(self, start_block, end_block):
# First of all, was any transaction confirmed in this block?
self.confirm_sequence(block)

# We always try to keep the number of expected vaults under watch. We might
# not be able to allocate if a CF tx is pending but not yet confirmed.
for i in range(len(self.wt.list_vaults()), self.num_vaults):
amount = int(10e10) # 100 BTC
try:
self.wt.allocate(self.new_vault_id(), amount, block)
except AllocationError as e:
logging.error(
f"Not enough funds to allocate all the expected vaults at block {block}: {str(e)}"
)
# FIXME: should we break?
break
self.vault_count += 1
if self.scale_fixed:
# We always try to keep the number of expected vaults under watch. We might
# not be able to allocate if a CF tx is pending but not yet confirmed.
for i in range(len(self.wt.list_vaults()), self.num_vaults):
amount = int(10e10) # 100 BTC
try:
self.wt.allocate(self.new_vault_id(), amount, block)
except AllocationError as e:
logging.error(
"Not enough funds to allocate all the expected vaults at"
f" block {block}: {str(e)}"
)
break
self.vault_count += 1

# Refill once per refill period
if block % self.refill_period == 0:
self.refill_sequence(block, 0)

# The unvault rate is a rate per day
# The delegate rate is per day
if not self.scale_fixed:
if random.random() < self.delegate_rate / BLOCKS_PER_DAY:
self.delegate_sequence(block)

# The spend rate is a rate per day
if random.random() < self.unvault_rate / BLOCKS_PER_DAY:
self.delegate_sequence(block)
if self.scale_fixed:
self.delegate_sequence(block)

# generate invalid spend, requires cancel
if random.random() < self.invalid_spend_rate:
try:
Expand Down Expand Up @@ -865,8 +872,14 @@ def plot(self, output=None, show=False):
plot_num += 1

# Report confirmation tracking
report += f"Max confirmation time for a Cancel Tx: {self.report_df['max_cancel_conf_time'][0]}\n"
report += f"Max confirmation time for a Consolidate-fanout Tx: {self.report_df['max_cf_conf_time'][0]}\n"
report += (
"Max confirmation time for a Cancel Tx:"
f" {self.report_df['max_cancel_conf_time'][0]}\n"
)
report += (
"Max confirmation time for a Consolidate-fanout Tx:"
f" {self.report_df['max_cf_conf_time'][0]}\n"
)

if output is not None:
plt.savefig(f"{output}.png")
Expand Down Expand Up @@ -970,6 +983,8 @@ def plot_fee_estimate(
unvault_rate=1,
invalid_spend_rate=0.1,
catastrophe_rate=0.05,
delegate_rate=1,
with_scale_fixed=True,
with_balance=True,
with_divergence=True,
with_op_cost=False,
Expand All @@ -982,7 +997,7 @@ def plot_fee_estimate(
with_fb_coins_dist=False,
)

start_block = 200000
start_block = 350000
end_block = 680000

sim.run(start_block, end_block)
Expand Down
5 changes: 1 addition & 4 deletions Model/statemachine.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
"""
TODO:
* simulate requirement for cancel feebump, then implement feebump algo
* Add random time interval between balance low and re-fill trigger (to simulate slow stakeholder),
to investigate time-at-risk.
* Make good documentation
* Remove possibility for inconsistencies in progress of blocks with WTSim
- could break with certain DELEGATION_PERIODs.
* Make good documentation
"""

import bisect
Expand Down