Browse Source

Add calculate fidelity bond value function + tests

master
chris-belcher 5 years ago
parent
commit
e6c084745c
No known key found for this signature in database
GPG Key ID: EF734EA677F31129
  1. 20
      jmclient/jmclient/wallet.py
  2. 61
      jmclient/test/test_wallet.py

20
jmclient/jmclient/wallet.py

@ -17,6 +17,7 @@ from hashlib import sha256
from itertools import chain from itertools import chain
from decimal import Decimal from decimal import Decimal
from numbers import Integral from numbers import Integral
from math import exp
from .configure import jm_single from .configure import jm_single
@ -2380,6 +2381,25 @@ class FidelityBondMixin(object):
self._storage.data[self._BURNER_OUTPUT_STORAGE_KEY][path][2] = \ self._storage.data[self._BURNER_OUTPUT_STORAGE_KEY][path][2] = \
merkle_branch merkle_branch
@classmethod
def calculate_timelocked_fidelity_bond_value(cls, utxo_value, confirmation_time, locktime,
current_time, interest_rate):
"""
utxo_value is in satoshi
interest rate is per year
all times are seconds
"""
YEAR = 60 * 60 * 24 * 365.2425 #gregorian calender year length
r = interest_rate
T = (locktime - confirmation_time) / YEAR
L = locktime / YEAR
t = current_time / YEAR
a = max(0, min(1, exp(r*T) - 1) - min(1, exp(r*max(0, t-L)) - 1))
return utxo_value*utxo_value*a*a
class BIP49Wallet(BIP32PurposedWallet): class BIP49Wallet(BIP32PurposedWallet):
_PURPOSE = 2**31 + 49 _PURPOSE = 2**31 + 49
_ENGINE = ENGINES[TYPE_P2SH_P2WPKH] _ENGINE = ENGINES[TYPE_P2SH_P2WPKH]

61
jmclient/test/test_wallet.py

@ -821,6 +821,67 @@ def test_watchonly_wallet(setup_wallet):
assert script == watchonly_script assert script == watchonly_script
assert burn_pubkey == watchonly_burn_pubkey assert burn_pubkey == watchonly_burn_pubkey
def test_calculate_timelocked_fidelity_bond_value(setup_wallet):
EPSILON = 0.000001
YEAR = 60*60*24*356.25
#the function should be flat anywhere before the locktime ends
values = [FidelityBondMixin.calculate_timelocked_fidelity_bond_value(
utxo_value=100000000,
confirmation_time=0,
locktime=6*YEAR,
current_time=y*YEAR,
interest_rate=0.01
)
for y in range(4)
]
value_diff = [values[i] - values[i+1] for i in range(len(values)-1)]
for vd in value_diff:
assert abs(vd) < EPSILON
#after locktime, the value should go down
values = [FidelityBondMixin.calculate_timelocked_fidelity_bond_value(
utxo_value=100000000,
confirmation_time=0,
locktime=6*YEAR,
current_time=(6+y)*YEAR,
interest_rate=0.01
)
for y in range(5)
]
value_diff = [values[i+1] - values[i] for i in range(len(values)-1)]
for vrd in value_diff:
assert vrd < 0
#value of a bond goes up as the locktime goes up
values = [FidelityBondMixin.calculate_timelocked_fidelity_bond_value(
utxo_value=100000000,
confirmation_time=0,
locktime=y*YEAR,
current_time=0,
interest_rate=0.01
)
for y in range(5)
]
value_ratio = [values[i] / values[i+1] for i in range(len(values)-1)]
value_ratio_diff = [value_ratio[i] - value_ratio[i+1] for i in range(len(value_ratio)-1)]
for vrd in value_ratio_diff:
assert vrd < 0
#value of a bond locked into the far future is constant, clamped at the value of burned coins
values = [FidelityBondMixin.calculate_timelocked_fidelity_bond_value(
utxo_value=100000000,
confirmation_time=0,
locktime=(200+y)*YEAR,
current_time=0,
interest_rate=0.01
)
for y in range(5)
]
value_diff = [values[i] - values[i+1] for i in range(len(values)-1)]
for vd in value_diff:
assert abs(vd) < EPSILON
@pytest.mark.parametrize('password, wallet_cls', [ @pytest.mark.parametrize('password, wallet_cls', [
["hunter2", SegwitLegacyWallet], ["hunter2", SegwitLegacyWallet],
["hunter2", SegwitWallet], ["hunter2", SegwitWallet],

Loading…
Cancel
Save