Skip to content

Instantly share code, notes, and snippets.

@brianddk
Last active July 13, 2019 08:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brianddk/1f339832a677aa941c7c16a7aeac8735 to your computer and use it in GitHub Desktop.
Save brianddk/1f339832a677aa941c7c16a7aeac8735 to your computer and use it in GitHub Desktop.
Bitcoin Lightning Fee simulator

Lighting network simulator

This is a very simple python program that will simulate a few conditions. For the ground work lets set up an Alice and Bob story.

Bob's friend Alice sets up a coffee shop. She is going to start taking cryptocurrency at the coffee shop, so she is set up to accept Bitcoin Cash (BCH) and Bitcoin Core via Lightning (BTCLN). Bob has a substantial holding in both BTC and BCH, though it is all in cold storage in a HW wallet. He does have a Coinbase account but is always very careful to calculate trading fees. So now Bob wants to determine what would be the best way to get ready to move his daily coffee patronage to Alice's shop.

Looking over his past expenses on morning coffee, he decides that 20,000 satoshis (BTC) should be a nice round number for lattes and perhaps 19,000 for coffee. Since BTC is trading at $10,600, his budget in terms of fiat comes out to just about $2 a day. With his budget in hand, he goes about reviewing the BCH and BTCLN payment options. He suspects BTC (mainnet) is too costly since he doesn't want to leave Alice with low priority economical transactions to chase.

Bitcoin Cash

His simplest solution of course is just to move BCH from his HW wallet (cold) to his mobile wallet (hot), but he wants to keep his BTC and BCH accounts fairly balanced and doesn't want to deplete his BCH funds entirely. He also wants to pay Alice in both BCH and BTCLN since she seemed excited about her new Point Of Sale system. He had thought about converting some of his BCH to BTC, though he realizes that there is always a cost for this on Coinbase (usually 0.15%).

Eclair LN Wallet

The next wallet Bob looked at was the Eclair mobile LN wallet. This would be simplest to fund with BTC which of course would have costs in moving funds from his HW wallet to Eclair, and then even more costs opening and closing a channel. He also noted on the github for the project that many LN wallets do not allow fees to be set on channel close operations. This might get costly as market fee rates rise.

Wallet of Satoshi, funded by a BTCLN exchange.

Another popular LN solution is Wallet of Satoshi (WoS). WoS seems like a simple solution since it doesn't have the same constraints on incoming and outgoing capacity like Eclair does. There is also no need to do any complicated channel setup since it is custodial and that is all just handled. Bob does realize that WoS funding options might be costly. He researches to ways to load and unload WoS using the FixedFloat exchange as well as the bitrefill Thor channel services.

FixedFloat for BCH funding and withdrawals from WoS

As noted before with WoS, LN transactions are seamless enough, but WoS has no way to convert funds back to BTC. For this we have to use a LN exchange. FixedFloat is a fairly reasonable exchange offering competitive exchange rates and a 0.5% fee. To convert funds from BTC, WoS has offers a comptitive rate of 0.3%, so obviously this is the simplest way to fund the wallet.

Bitrefill for BTC funding

Although not a verify competitive option, the Bitrefill funding option is included here just to see how it stacks up to the others.

Results

I've included two runs of the simluator in LibreOffice format. They should be viewable in Google Sheets, Excel or LibreOffice

Latte (without bugfix)

This simulated buying lattes (20k) and compared the cost of using various wallets. Important inflection points that were found:

  • 17 cups / 3.6 mBTC - If spending less than 3.6 mBTC, it is cheaper to convert the BTC to BCH and just use a BCH wallet. At 17 cups however, using the WoS LN wallet is the cheapest way to spend BTC.
  • 39 cups / 8.0 mBTC - If spending less than 8.0 mBTC, it is cheaper to fund your WoS LN using BCH. At 39 cups it becomes less expensive to use BTC to fund your WoS LN wallet.

Coffee (with bugfix)

This simulated buying coffees (10k) and compared the cost of using various wallets. Important inflection points that were found. This simulation did assume that the expensive channel close bug in Eclair was fixed:

  • 4 cups / 1.9 mBTC - If spending less than 1.9 mBTC, it is cheaper to convert the BTC to BCH and just use a BCH wallet. At 4 cups however, using the WoS LN wallet is the cheapest way to spend BTC.
  • 41 cups / 8.0 mBTC - If spending less than 8.0 mBTC, it is cheaper to fund your WoS LN using BCH. At 41 cups it becomes less expensive to use BTC to fund your WoS LN wallet.
  • 853 cups / 163 mBTC - If spending less than 163 mBTC, the average TXN cost of using BCH is cheaper than using BTCLN. At 853 cups (yikes) however, it is cheaper to use BTCLN for coffee than to use BCH.

Files

  • +README.md - This file (named for sorting)
  • lnsim.py - The python file to run the sims, produces CSV to stdout
  • latte.ods - LibreOffice file of sim run for latte prices (no bugfix applied). Select view-raw to download.
  • coffee-bugfix.ods - LibreOffice file of sim run for coffee prices (w/bugfix). Select view-raw to download.
  • bch.json - BCH fee file to use as an argument to compare to LN wallets
  • ltc.json - LTC fee file to use as an argument to compare to LN wallets
  • .gitignore - A git artifact, as it suggests... please ignore.

Usage

To run this, do the following:

  1. git clone https://gist.github.com/brianddk/1f339832a677aa941c7c16a7aeac8735 lnsim to get files.
  2. Edit lnsim.py and update the defines at top of the file to your liking
  3. python3 lnsim.py coin.json > results.csv or python.exe in windows
  4. Open results.csv in LibreOffice

Tips

Coin Address / QR
BTCLN https://tippin.me/@dkbriand
LTC MKcAge42cX6WZnnPfFGJAxReUYZUbsi6t3
LTC-b32 ltc1q5uucgx9f8n70nq7jmjy03rpg84cm4tm70z5rz6
BCH-b32 qqz77k4rqar3uppj8k28de06narwkqaamcf624p8zl
ETH / BAT 0xBc72A79357Ff7A59265725ECB1A9bFa59330DB4b
__pycache__/
WalletSize #1 #2 #3 #4 #5 #6 #7
11:4:5 Bch:0:1:0 WosFF:0:1:0 WosFF:0:0:0 WosBR:0:1:0 WosBR:0:0:0 Eclair+:1:0:0 Btc:0:1:0
24:4:12 Bch:0:1:0 WosFF:0:1:0 WosFF:0:0:0 WosBR:0:1:0 Eclair+:1:0:0 WosBR:0:0:0 Btc:0:1:0
28:4:14 Bch:0:1:0 WosFF:0:1:0 WosFF:0:0:0 Eclair+:1:0:0 WosBR:0:1:0 WosBR:0:0:0 Btc:0:1:0
60:4:31 Bch:0:1:0 WosFF:0:1:0 WosFF:0:0:0 Eclair+:1:0:0 WosBR:0:0:0 WosBR:0:1:0 Btc:0:0:0
79:4:41 Bch:0:1:0 WosFF:0:0:0 WosFF:0:1:0 Eclair+:1:0:0 WosBR:0:0:0 WosBR:0:1:0 Btc:0:0:0
127:4:66 Bch:0:1:0 WosFF:0:0:0 Eclair+:1:0:0 WosFF:0:1:0 WosBR:0:0:0 WosBR:0:1:0 Btc:0:0:0
157:4:82 Bch:0:1:0 Eclair+:1:0:0 WosFF:0:0:0 WosFF:0:1:0 WosBR:0:0:0 WosBR:0:1:0 Btc:0:0:0
1626:4:853 Eclair+:1:0:0 Bch:0:1:0 WosFF:0:0:0 WosFF:0:1:0 WosBR:0:0:0 WosBR:0:1:0 Btc:0:0:0
{
"name": "Bch",
"latte": false,
"bugfix": true,
"txn_coffee": 19000,
"txn_latte": 20000,
"classes": [ "Eclair", "WosFF", "WosBR", "Btc", "Alt" ],
"scale": 100000000,
"lo_pri": 1602,
"hi_pri": 17404,
"alt_btc_hi": 3769000,
"alt_btc_low": 3760000,
"alt_pri": 226,
"ln_pri": 1,
"cex_fee": 0.0015,
"wos_fee": 0.003,
"dex_fee": 0.005,
"brefill_fee": 0.02,
"reserve": 22000,
"cycles": 5000,
"markdown": true,
"excludes": [
"Bch:0:0:0",
"Bch:1:0:0",
"Bch:1:0:1",
"Bch:1:1:0",
"Bch:1:1:1",
"WosBR:1:0:0",
"WosBR:1:0:1",
"WosBR:1:1:0",
"WosBR:1:1:1",
"Btc:1:0:0",
"Btc:1:0:1",
"Btc:1:1:0",
"Btc:1:1:1",
"Eclair+:1:0:1",
"Eclair+:1:1:0",
"Eclair+:1:1:1",
"WosFF:1:0:0",
"WosFF:1:0:1",
"WosFF:1:1:0",
"WosFF:1:1:1"
]
}
WalletSize #1 #2 #3 #4 #5 #6 #7
11:77:5 WosFF:0:1:0 Eth:0:1:0 WosFF:0:0:0 WosBR:0:1:0 WosBR:0:0:0 Btc:0:1:0 Btc:0:0:0
13:73:6 WosFF:0:1:0 WosFF:0:0:0 Eth:0:1:0 WosBR:0:1:0 WosBR:0:0:0 Btc:0:1:0 Btc:0:0:0
28:61:14 WosFF:0:1:0 WosFF:0:0:0 Eth:0:1:0 WosBR:0:1:0 WosBR:0:0:0 Btc:0:1:0 Eclair:1:0:0
30:61:15 WosFF:0:1:0 WosFF:0:0:0 Eth:0:1:0 WosBR:0:1:0 WosBR:0:0:0 Eclair:1:0:0 Btc:0:1:0
66:55:34 WosFF:0:0:0 WosFF:0:1:0 Eth:0:1:0 WosBR:0:1:0 WosBR:0:0:0 Eclair:1:0:0 Btc:0:1:0
76:52:39 WosFF:0:0:0 WosFF:0:1:0 Eth:0:1:0 WosBR:0:0:0 WosBR:0:1:0 Eclair:1:0:0 Btc:0:0:0
102:47:53 WosFF:0:0:0 WosFF:0:1:0 Eth:0:1:0 WosBR:0:0:0 Eclair:1:0:0 WosBR:0:1:0 Btc:0:0:0
104:46:54 WosFF:0:0:0 WosFF:0:1:0 Eth:0:1:0 Eclair:1:0:0 WosBR:0:0:0 WosBR:0:1:0 Btc:0:0:0
146:42:76 WosFF:0:0:0 WosFF:0:1:0 Eclair:1:0:0 Eth:0:1:0 WosBR:0:0:0 WosBR:0:1:0 Btc:0:0:0
435:35:227 WosFF:0:0:0 Eclair:1:0:0 WosFF:0:1:0 Eth:0:1:0 WosBR:0:0:0 WosBR:0:1:0 Btc:0:0:0
676:33:354 Eclair:1:0:0 WosFF:0:0:0 WosFF:0:1:0 Eth:0:1:0 WosBR:0:0:0 WosBR:0:1:0 Btc:0:0:0
{
"name": "Eth",
"latte": false,
"bugfix": false,
"txn_coffee": 19000,
"txn_latte": 20000,
"classes": [ "Eclair", "WosFF", "WosBR", "Btc", "Alt" ],
"scale": 100000000,
"lo_pri": 1602,
"hi_pri": 17404,
"alt_btc_hi": 2562200,
"alt_btc_low": 2561000,
"alt_pri": 11481,
"ln_pri": 1,
"cex_fee": 0.0015,
"wos_fee": 0.003,
"dex_fee": 0.005,
"brefill_fee": 0.02,
"reserve": 22000,
"cycles": 5000,
"markdown": true,
"excludes": [
"Eth:0:0:0",
"Eth:1:0:0",
"Eth:1:0:1",
"Eth:1:1:0",
"Eth:1:1:1",
"WosBR:1:0:0",
"WosBR:1:0:1",
"WosBR:1:1:0",
"WosBR:1:1:1",
"Btc:1:0:0",
"Btc:1:0:1",
"Btc:1:1:0",
"Btc:1:1:1",
"Eclair:1:0:1",
"Eclair:1:1:0",
"Eclair:1:1:1",
"WosFF:1:0:0",
"WosFF:1:0:1",
"WosFF:1:1:0",
"WosFF:1:1:1"
]
}
WalletSize #1 #2 #3
11:171:5 WosFF:0:0:0 WosBR:0:0:0 Btc:0:0:0
28:87:14 WosFF:0:0:0 WosBR:0:0:0 Eclair:1:0:0
104:46:54 WosFF:0:0:0 Eclair:1:0:0 WosBR:0:0:0
676:33:354 Eclair:1:0:0 WosFF:0:0:0 WosBR:0:0:0
{
"name": "Nop",
"latte": false,
"bugfix": false,
"txn_coffee": 19000,
"txn_latte": 20000,
"classes": [ "Eclair", "WosFF", "WosBR", "Btc" ],
"scale": 100000000,
"lo_pri": 1602,
"hi_pri": 17404,
"alt_btc_hi": 100000000,
"alt_btc_low": 100000000,
"alt_pri": 1602,
"ln_pri": 1,
"cex_fee": 0.0015,
"wos_fee": 0.003,
"dex_fee": 0.005,
"brefill_fee": 0.02,
"reserve": 22000,
"cycles": 5000,
"markdown": true,
"excludes": [
"WosBR:0:1:0",
"WosBR:1:0:0",
"WosBR:1:0:1",
"WosBR:1:1:0",
"WosBR:1:1:1",
"Btc:0:1:0",
"Btc:1:0:0",
"Btc:1:0:1",
"Btc:1:1:0",
"Btc:1:1:1",
"Eclair:1:0:1",
"Eclair:1:1:0",
"Eclair:1:1:1",
"WosFF:0:1:0",
"WosFF:1:0:0",
"WosFF:1:0:1",
"WosFF:1:1:0",
"WosFF:1:1:1"
]
}
#!/usr/bin/env python3
# [rights] Copyright brianddk 2019 https://github.com/brianddk
# [license] Apache 2.0 License https://www.apache.org/licenses/LICENSE-2.0
# [repo] https://gist.github.com/brianddk/1f339832a677aa941c7c16a7aeac8735
# [bchtip] BCH: bitcoincash:qqz77k4rqar3uppj8k28de06narwkqaamcf624p8zl
# [tipjar] https://gist.github.com/brianddk/3ec16fbf1d008ea290b0
# [refered] https://www.reddit.com/[tbd]
# [usage] python3 lnsim.py coin.json > results.csv
default_coin = "bch.json"
from collections import namedtuple
from json import load
from sys import argv, modules
def load_coin(coin_json = default_coin):
with open(coin_json) as f:
data = load(f)
name = data["name"]
return namedtuple(name, data.keys())(*data.values())
if __name__ == "__main__":
fname = default_coin if len(argv) < 2 else argv[1]
coin = load_coin(fname)
class InsufficentFundsError(Exception):
"""Ran out of satoshis for coffee"""
pass
class WalletSim:
"""A superclass for various spend simulators"""
coin = load_coin() if 'coin' not in globals() else coin
# DEFINES - Edit these to your liking
name = coin.name # name of the coin we are comparing
latte = coin.latte # whether to use latte or coffee pricing
bugfix = coin.bugfix # whether the Eclair close bug is fixed
txn_coffee = coin.txn_coffee # 19,000 sat is the price of coffee
txn_latte = coin.txn_latte # 20,000 sat is the price of latte
scale = coin.scale # 100 million sat = 1 BTC
lo_pri = coin.lo_pri # BTC sat TXN cost for low priority
hi_pri = coin.hi_pri # BTC sat TXN cost for hi priority
alt_btc_hi = coin.alt_btc_hi # BTC sat costs for 1 COIN on sell-book
alt_btc_low = coin.alt_btc_low # BTC sat costs for 1 COIN on buy-book
alt_pri = coin.alt_pri # COIN sat TXN cost for hi priority
ln_pri = coin.ln_pri # LN sat TXN cost for single TXN
cex_fee = coin.cex_fee # 0.15% fee for limit orders at Coinbase
wos_fee = coin.wos_fee # 0.30% fee for BTC conversion at WoS
dex_fee = coin.dex_fee # 0.50% fee for BTC or COIN at FixedFloat
brefill_fee = coin.brefill_fee # 2.00% fee for BTC conv at Bitrefill
reserve = coin.reserve # Eclair channel reserve for future fees
cycles = coin.cycles # Number of loops in simulation
markdown = coin.markdown # Format output for CSV or markdown
excludes = coin.excludes # List of excluded objects
txn_size = txn_latte if latte else txn_coffee # latte or coffee
alt_btc_fair= (alt_btc_hi + alt_btc_low) / 2 # fair price from conv
alt_spnd = alt_pri * alt_btc_fair / scale # conv to BTC sat
# /end DEFINES
def __init__(self, init, txns, rtn, inalt, outalt):
self.spnd_fee = self.ln_pri
self.bal = init
self.init = init
self.txns = txns
self.return_funds = rtn
self.inalt = inalt
self.outalt = outalt
def __str__(self):
selfstr = type(self).__name__
if selfstr == "Eclair" and self.bugfix:
selfstr = "Eclair+"
else:
selfstr = self.name if selfstr == "Alt" else selfstr
selfstr += ":1" if self.return_funds else ":0"
selfstr += ":1" if self.inalt else ":0"
selfstr += ":1" if self.outalt else ":0"
return selfstr
def spend(self):
self.bal -= self.txns * (self.spnd_fee + self.txn_size)
if self.bal <= 0: raise InsufficentFundsError()
def run_sim(self):
if self.inalt: self.fund_alt()
else: self.fund_btc()
self.spend()
if self.return_funds:
if self.outalt: self.return_alt()
else: self.return_btc()
return self.init - (self.bal + self.txn_size * self.txns)
class Eclair(WalletSim):
"""A Eclair wallet simulator"""
def __init__(self, init, txns, rtn, inalt, outalt):
super().__init__(init, txns, rtn, inalt, outalt)
self.fees = self.run_sim()
def fund_btc(self):
# HW wal to Eclair
self.bal -= self.lo_pri
# Eclair chan open
self.bal -= self.lo_pri
# hold reserve
self.bal -= self.reserve
def fund_alt(self):
# HW-wal to CEX
self.bal -= self.alt_spnd
# CEX Fee
self.bal -= self.bal * self.cex_fee
# Eat spread & send to Eclair
self.bal *= self.alt_btc_low / self.alt_btc_fair
# Eclair chan open
self.bal -= self.lo_pri
# hold reserve
self.bal -= self.reserve
def return_btc(self):
# return reserve
self.bal += self.reserve
# Chan close
self.bal -= self.lo_pri if self.bugfix else self.hi_pri
# BTC to trez
self.bal -= self.lo_pri
def return_alt(self):
# btc to CEX
self.return_btc()
# CEX Fee
self.bal -= self.bal * self.cex_fee
# Eat spread & send along
self.bal *= self.alt_btc_fair / self.alt_btc_hi
class WosWallet(WalletSim):
"""A WoS based wallet"""
def __init__(self, init, txns, rtn, inalt, outalt):
super().__init__(init, txns, rtn, inalt, outalt)
self.spnd_fee = 2 * self.ln_pri # WoS adds a 1 sat fee to most TXNs
self.fees = self.run_sim()
def return_btc(self):
# WoS to DEX
self.bal -= self.spnd_fee
# DEX Fee
self.bal -= self.bal * self.dex_fee
# DEX to HW-wal
self.bal -= self.hi_pri
def return_alt(self):
# WoS to DEX
self.bal -= self.ln_pri
# DEX Fee
self.bal -= self.bal * self.dex_fee
# DEX to HW-wal
self.bal -= self.alt_spnd
class WosFF(WosWallet):
"""A FixedFloat wallet simulator"""
def fund_btc(self):
# HW wal to WoS
self.bal -= self.lo_pri
# WoS conversion fee
self.bal -= self.bal * self.wos_fee
def fund_alt(self):
# HW-wal to DEX
self.bal -= self.alt_spnd
# DEX Fee
self.bal -= self.bal * self.dex_fee
# DEX to WoS
self.bal -= self.ln_pri
class WosBR(WosWallet):
"""A Bitrefill wallet simulator"""
def fund_btc(self):
# HW wal to CB
self.bal -= self.lo_pri
# bitrefill fee
self.bal -= self.bal * self.brefill_fee
def fund_alt(self):
# HW-wal to CB
self.bal -= self.alt_spnd
# CEX Fee
self.bal -= self.bal * self.cex_fee
# Eat spread
self.bal *= self.alt_btc_low / self.alt_btc_fair
# bitrefill fee
self.bal -= self.bal * self.brefill_fee
class ChainWallet(WalletSim):
"""A WoS based wallet"""
def btc_to_alt(self):
# HW-wal to CEX
self.bal -= self.lo_pri
# CEX Fee
self.bal -= self.bal * self.cex_fee
# Eat spread & send along
self.bal *= self.alt_btc_fair / self.alt_btc_hi
def alt_to_btc(self):
# HW-wal to CEX
self.bal -= self.alt_spnd
# CEX Fee
self.bal -= self.bal * self.cex_fee
# Eat spread & send along
self.bal *= self.alt_btc_low / self.alt_btc_fair
class Alt(ChainWallet):
"""A COIN wallet simulator"""
def __init__(self, init, txns, rtn, inalt, outalt):
super().__init__(init, txns, rtn, inalt, outalt)
self.spnd_fee = self.alt_spnd
self.fees = self.run_sim()
def fund_btc(self):
self.btc_to_alt()
def fund_alt(self):
# HW-wal to SW-wal
self.bal -= self.alt_spnd
def return_btc(self):
self.alt_to_btc()
def return_alt(self):
# SW-wal to HW-wal
self.bal -= self.alt_spnd
class Btc(ChainWallet):
"""A BTC wallet simulator"""
def __init__(self, init, txns, rtn, inalt, outalt):
super().__init__(init, txns, rtn, inalt, outalt)
self.spnd_fee = self.lo_pri
self.fees = self.run_sim()
def fund_btc(self):
# HW-wal to SW-wal
self.bal -= self.lo_pri
def fund_alt(self):
self.alt_to_btc()
def return_btc(self):
# SW-wal to HW-wal
self.bal -= self.lo_pri
def return_alt(self):
self.btc_to_alt()
def mk_header(ncol):
header = ""
for i in range(0, ncol):
if i:
header += delim + "**#" + str(i) + "**"
else:
header += "**WalletSize**"
print(header)
if WalletSim.markdown:
header = ""
for i in range(0, ncol):
header += delim + ":--"
print(header[len(delim):])
def mk_line(i, lst, cur, prv, ncol, mute):
init = i * txn_size # starting balance
if init > maxln: return (cur, ncol) # abort if too high
if init < minln: return (cur, ncol) # abort if too low
ncol = tmax = 0 # max successful wallet TXNs
fmin = 10_000 # 100th of percent fees
for cls_ in coin.classes: # string of class names
cls = getattr(modules[__name__], cls_) # class handle from str
txns = init // txn_size # integer div for number of TXNs
for rtn in [True, False]: # return change to on-chain or not
for inalt in [True, False]: # fund LN from alt-coin or not
for outalt in [True, False]: # return change in alt or not
if not rtn and outalt: # if we don't return change
continue # - then we don't care
if not rtn and cls_ == "Eclair": # if eclair
continue # only count returns
while txns > 0: # try default # of TXNs
try: # try/catch negative balance
obj = cls(init, txns, rtn, inalt, outalt)
break # It worked... quick break!
except InsufficentFundsError:
txns -= 1 # failed, try fewer TXNs
if str(obj) in WalletSim.excludes: # if obj excluded
continue # - then skip this object
lst.append(obj) # success... add obj to list
tmax = max(tmax, txns) # record max TXN for this run
fmin = min(fmin, round(obj.fees / init * 10_000))
lst.sort(key=lambda x: x.fees) # sort list based on lowest fees
ncol = len(lst) # number of columns for header
cur = [str(x) for x in lst] # stringify list of objects
if prv != cur: # is this string unique?
btc = init // 10_000 # beautify, format wallet size
bal = str(btc) + ":" + str(fmin) + ":" + str(tmax) # of TXNs
line = delim.join([bal] + [str(x) for x in lst]) # output line.
if not WalletSim.markdown:
line = '"' + line + '"'
if not mute: print(line) # output line.
return (cur, ncol)
if __name__ == "__main__":
txn_size = WalletSim.txn_size # Price of coffee or latte
scale = WalletSim.scale # 1 BTC = 10,000,000 sat
delim = " | " if WalletSim.markdown else '", "' # CSV or Markdown delim
ncol = cur = prv = None # initialize state vars
maxln = (1 << 24) - 1 # max ln chan. per BOLT002
minln = 100_000 # assume $10 min
(ncol, ncol) = mk_line((maxln / txn_size // 2), [], cur, prv, ncol, mute=True)
mk_header(ncol)
for i in range(2, WalletSim.cycles): # assume at least 2 cycles
(cur, ncol) = mk_line(i, [], cur, prv, ncol, mute=False)
prv = cur
WalletSize #1 #2 #3 #4 #5 #6 #7
11:46:5 Ltc:0:1:0 WosFF:0:1:0 WosFF:0:0:0 WosBR:0:1:0 WosBR:0:0:0 Btc:0:1:0 Btc:0:0:0
28:46:14 Ltc:0:1:0 WosFF:0:1:0 WosFF:0:0:0 WosBR:0:1:0 WosBR:0:0:0 Btc:0:1:0 Eclair:1:0:0
30:46:15 Ltc:0:1:0 WosFF:0:1:0 WosFF:0:0:0 WosBR:0:1:0 WosBR:0:0:0 Eclair:1:0:0 Btc:0:1:0
62:46:32 Ltc:0:1:0 WosFF:0:1:0 WosFF:0:0:0 WosBR:0:0:0 WosBR:0:1:0 Eclair:1:0:0 Btc:0:0:0
76:46:39 Ltc:0:1:0 WosFF:0:0:0 WosFF:0:1:0 WosBR:0:0:0 WosBR:0:1:0 Eclair:1:0:0 Btc:0:0:0
98:46:51 Ltc:0:1:0 WosFF:0:0:0 WosFF:0:1:0 WosBR:0:0:0 Eclair:1:0:0 WosBR:0:1:0 Btc:0:0:0
104:46:54 Ltc:0:1:0 WosFF:0:0:0 WosFF:0:1:0 Eclair:1:0:0 WosBR:0:0:0 WosBR:0:1:0 Btc:0:0:0
106:46:55 WosFF:0:0:0 Ltc:0:1:0 WosFF:0:1:0 Eclair:1:0:0 WosBR:0:0:0 WosBR:0:1:0 Btc:0:0:0
438:35:229 WosFF:0:0:0 Ltc:0:1:0 Eclair:1:0:0 WosFF:0:1:0 WosBR:0:0:0 WosBR:0:1:0 Btc:0:0:0
490:34:256 WosFF:0:0:0 Eclair:1:0:0 Ltc:0:1:0 WosFF:0:1:0 WosBR:0:0:0 WosBR:0:1:0 Btc:0:0:0
676:33:354 Eclair:1:0:0 WosFF:0:0:0 Ltc:0:1:0 WosFF:0:1:0 WosBR:0:0:0 WosBR:0:1:0 Btc:0:0:0
{
"name": "Ltc",
"latte": false,
"bugfix": false,
"txn_coffee": 19000,
"txn_latte": 20000,
"classes": [ "Eclair", "WosFF", "WosBR", "Btc", "Alt" ],
"scale": 100000000,
"lo_pri": 1602,
"hi_pri": 17404,
"alt_btc_hi": 1058100,
"alt_btc_low": 1056100,
"alt_pri": 8286,
"ln_pri": 1,
"cex_fee": 0.0015,
"wos_fee": 0.003,
"dex_fee": 0.005,
"brefill_fee": 0.02,
"reserve": 22000,
"cycles": 5000,
"markdown": true,
"excludes": [
"Ltc:0:0:0",
"Ltc:1:0:0",
"Ltc:1:0:1",
"Ltc:1:1:0",
"Ltc:1:1:1",
"WosBR:1:0:0",
"WosBR:1:0:1",
"WosBR:1:1:0",
"WosBR:1:1:1",
"Btc:1:0:0",
"Btc:1:0:1",
"Btc:1:1:0",
"Btc:1:1:1",
"Eclair:1:0:1",
"Eclair:1:1:0",
"Eclair:1:1:1",
"WosFF:1:0:0",
"WosFF:1:0:1",
"WosFF:1:1:0",
"WosFF:1:1:1"
]
}
@brianddk
Copy link
Author

brianddk commented Jul 3, 2019

Please leave a comment if you have any questions or corrections.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment