<oembed><type>rich</type><version>1.0</version><author_name>npub1g5zswf6y48f7fy90jf3tlcuwdmjn8znhzaa4vkmtxaeskca8hpss23ms3l</author_name><author_url>https://nostr.ae/npub1g5zswf6y48f7fy90jf3tlcuwdmjn8znhzaa4vkmtxaeskca8hpss23ms3l</author_url><provider_name>njump</provider_name><provider_url>https://nostr.ae</provider_url><html>📅 Original date posted:2021-08-20&#xA;📝 Original message:&#xA;Subject: Fee Budgets: A Possible Path Towards Unified Cost Functions For Lightning Pathfinding Problems&#xA;&#xA;Introduction&#xA;============&#xA;&#xA;What is the cost of a failed LN payment?&#xA;&#xA;Presumably, if a user wants to pay in exchange for something,&#xA;that user values that thing higher than the Bitcoin they spend&#xA;on that thing.&#xA;This is a central assumption of free market economics, that&#xA;all transactions are voluntary and that all participants in&#xA;the transaction get more utility out of the transaction than&#xA;what they put in.&#xA;&#xA;Note that ***value is subjective***.&#xA;For example, a farmer values the food they sell less than&#xA;the buyer of that food, because the farmer has leet farming&#xA;skillz that actually let them **grow food** from literal shit,&#xA;sunlight, and water, and presumably the buyer does not have&#xA;those leet skillz0rs to convert literal shit to food&#xA;using sunlight and water (otherwise they would be growing&#xA;their own food).&#xA;This applies for all production, given that you puny humans&#xA;have such limited time to learn and train leet skillz.&#xA;&#xA;Thus, for a buyer, there is a difference in value between&#xA;the product they are buying, and the BTC they are sacrificing&#xA;to the elder gods (i.e. the payment network and the seller) in&#xA;order to get the product.&#xA;The buyer must value the product more than the BTC.&#xA;&#xA;This difference, then, is the cost of a failed payment.&#xA;If the attempt to pay fails, then obviously the seller&#xA;will not be willing to send the product (as it can receive&#xA;no money for it) and the buyer loses the (buyer-subjective)&#xA;value of the product minus the value of the BTC they wanted&#xA;to use to pay.&#xA;&#xA;This difference in value, while subjective, is quantifiable&#xA;(consider how judges at a beauty contest must convert&#xA;their subjective judgment of beauty to a number; indeed,&#xA;horny humans do this all the time at bars, suggesting that&#xA;even judgment-impaired humans intuitively understand that&#xA;subjective values can be quantified).&#xA;And that quantifiable subjective value can be measured in&#xA;units of bitcoin.&#xA;&#xA;Thus, this difference in value is the cost of failure of an&#xA;LN payment.&#xA;And due to the relationship of failure and success, the&#xA;cost of failure is the value of success.&#xA;&#xA;Pickhardt-Richter Payments&#xA;==========================&#xA;&#xA;Why is the cost of failure/value of success even relevant?&#xA;&#xA;In [a 2021 paper](https://arxiv.org/abs/2107.05322)&#xA;Pickhardt and Richter present a method of estimating&#xA;the probability of payment success, and using that&#xA;probability-of-success as a cost function for a&#xA;generalization of pathfinding algorithms (specifically&#xA;minimum cost flow).&#xA;&#xA;Of course, probabilities of success are not the only&#xA;concern that actual pathfinding algorithms need to&#xA;worry about.&#xA;Another two concerns are:&#xA;&#xA;* Actual fees (measured in bitcoin units).&#xA;* Actual total cltv-delta (measured in blocks).&#xA;&#xA;It is possible to convert total cltv-delta to a &#34;Fee&#34;.&#xA;Basically, the cost of the total cltv-delta is the value&#xA;of your funds being locked and unuseable for that many&#xA;blocks.&#xA;This can be represented as an expected annual return on&#xA;investment if those funds were instead locked into some&#xA;investment.&#xA;In C-Lightning this is the `riskfactor` parameter.&#xA;&#xA;This implies that total cltv-delta can be converted&#xA;to an equivalent amount of BTCs.&#xA;&#xA;Now, the issue is, how can we convert probability of&#xA;success to some equivalent amount of BTCs?&#xA;&#xA;This is why the value of success --- i.e. the cost&#xA;of payment failure --- is relevant.&#xA;&#xA;By multiplying the cost of failure by the probability&#xA;of failure, we can acquire a bitcoins-measured&#xA;quantity that can be added directly to expected fees.&#xA;&#xA;Fee Budgets&#xA;===========&#xA;&#xA;Long ago, some weird rando with an unpronouncable name&#xA;decided to add a &#34;fee budget&#34; to his implementation of&#xA;C-Lightning pay algorithm (back when C-Lightning did not&#xA;even have a `pay` algorithm).&#xA;For some reason (possibly dark ritual), that rando managed&#xA;to get that code into the actual C-Lightning, and the&#xA;fee budget --- known as `maxfeepercent` --- has been&#xA;retained to this day, even though none of the original&#xA;code has survived (dark rituals tend to consume anything&#xA;involved in their rites, I would not be surprised if&#xA;that includes source code).&#xA;&#xA;Now consider --- how would a buyer assign a fee budget&#xA;for a particular payment?&#xA;&#xA;As we noted, a rational buyer will only buy if they&#xA;believe the value of the product being bought is higher&#xA;than the value of the BTCs they sacrifice to buy that&#xA;product.&#xA;This difference is the cost of failure (equivalent to&#xA;value of success).&#xA;&#xA;And a rational buyer will be willing to pay, as fee,&#xA;any value up to this cost of failure/value of success.&#xA;&#xA;For example, if the buyer is not willing to pay more&#xA;than half the cost of failure, then if there is no&#xA;way to succeed payments at half the cost of failure,&#xA;then the payment simply fails and the buyer loses&#xA;the entire cost of failure.&#xA;Logically, the buyer must be willing to pay, as&#xA;fees, up to the cost of failure.&#xA;&#xA;Similarly, if the buyer is willing to pay up to twice&#xA;the cost of failure, then if it succeeds only by&#xA;paying up to twice the cost of failure, even if the&#xA;payment pushes through and the buyer gets the product,&#xA;the buyer still lost the cost of failure because it&#xA;paid more fees than the value of the payment success&#xA;was.&#xA;&#xA;Logically, then, the buyer must specify as fee budget,&#xA;its expected value from acquiring the product minus&#xA;the price of the product.&#xA;&#xA;Thus, it so happens that the fee budget is, in fact,&#xA;the value of payment success/cost of payment failure,&#xA;subjectively determined by the payer, quantified, and&#xA;provided to the C-Lightning payment algorithm!&#xA;&#xA;Unified Cost Function&#xA;=====================&#xA;&#xA;The cost of failure is then:&#xA;&#xA;    fee_budget * (1 - success_probability)&#xA;&#xA;The `fee_budget` is the above fee budget, an input&#xA;from the user.&#xA;`success_probability` is the estimate as determined&#xA;using the Pickhardt-Richter algorithm.&#xA;&#xA;The cost of a channel that charges `fee` is:&#xA;&#xA;    fee + fee_budget * (1 - success_probability)&#xA;&#xA;However, we should note that the above cost function&#xA;is really the expected cost for the *entire&#xA;payment*.&#xA;In particular, `success_probability` is multiplicative&#xA;along a path, whereas `fee` is additive.&#xA;&#xA;When we consider multipath payments, we should also&#xA;observe that the `success_probability` of each&#xA;sub-payment are multiplied together (since all&#xA;sub-payments must succeed) while `fee` is again&#xA;additive in nature.&#xA;&#xA;Because of this, there is probably no *existing*&#xA;pathfinding algorithm which can actually *use*&#xA;this cost function.&#xA;Every pathfinding algorithm uses addition&#xA;to compute total costs.&#xA;&#xA;The Pickhardt-Richter paper gets around this by&#xA;using the logarithm of the probability.&#xA;As addition of logarithms is equivalent to&#xA;multiplication (`log A + log B = log (A * B)`),&#xA;this converts the addition operations of&#xA;existing pathfinding algos to multiplication of the&#xA;probabilities.&#xA;&#xA;This technique cannot work with the above unified&#xA;cost function, unfortunately.&#xA;&#xA;However, we can consider that, if we neglect&#xA;`fee`, and use only the logarithms of the cost&#xA;function, then the `fee_budget` term is&#xA;effectively a constant cost for all channels on&#xA;the network.&#xA;That is, `log (fee_budget * success_probability) =&#xA;log fee_budget + log success_probability`&#xA;for all channels on the network, and we can&#xA;subtract `log fee_budget` on all channels&#xA;without changing the result of any pathfinding&#xA;algorithms (provided we do not get into zero or&#xA;negative costs).&#xA;Thus, this instance of the Pickhard-Richter&#xA;technique is equivalent to neglecting both the&#xA;`fee` and the `fee_budget` in our unified cost&#xA;function.&#xA;&#xA;Generalized `#zerobasefee`&#xA;==========================&#xA;&#xA;If `fee` is small compared to `fee_budget`, then&#xA;we can consider the effect of the `fee` term to&#xA;be negligible compared to `fee_budget` term.&#xA;&#xA;Here is how the above cost function looks like,&#xA;with `fee_budget` distributed:&#xA;&#xA;    fee + fee_budget - fee_budget * success_probability&#xA;&#xA;If `fee_budget` is very much higher than `fee`&#xA;then we can neglect `fee` as an approximation.&#xA;&#xA;    fee_budget - fee_budget * success_probability&#xA;&#xA;Since `fee_budget` is constant for all paths and&#xA;for all channels, we can just use the negative&#xA;logarithm of `success_probability` as the cost&#xA;function.&#xA;&#xA;As a heuristic, we can *ignore* fees and&#xA;just use nagetive log probability, as suggested&#xA;in the Pickhardt-Richter paper, *after* pruning&#xA;channels whose fees are very high (i.e. prune&#xA;channels whose `fee`, say, exceeds 1% of the&#xA;`fee_budget`).&#xA;&#xA;One way to view `#zerobasefee` is that this is&#xA;a specialized instance of the above general&#xA;heuristic, that we can prune channels with&#xA;non-zero base fees in order to operate a&#xA;pathfinding algorithm that uses only addition&#xA;for edge costs and use negative log probability&#xA;for edge costs.&#xA;&#xA;We can instead consider that *small enough*&#xA;base fees, which are negligible compared to&#xA;the `fee_budget`, should not be pruned, and&#xA;not specifically that all non-zero base fees&#xA;should be pruned.&#xA;That is, `#zerobasefee` assumes that a 1-sat&#xA;base fee is *not* negligible compared to the&#xA;`fee_budget`.&#xA;&#xA;However, for large enough payments, the&#xA;`fee_budget` may be large enough that a 1&#xA;satoshi base fee is actually negligible&#xA;compared to the `fee_budget` term.&#xA;This implies that `#zerobasefee` is a&#xA;specific heuristic, one that potentially&#xA;could be generalized.&#xA;&#xA;As a corollary, the higher `success_probability`&#xA;is, the more small fees matter (since&#xA;`success_probability` subtracts from `fee_budget`).&#xA;And higher `success_probability` arises from&#xA;larger channels in general.&#xA;This leads to the counterintuition that&#xA;larger channels should charge lower fees,&#xA;since logically the `#lowbasefee` pruning level&#xA;should be lower at higher `success_probability`.&#xA;&#xA;Alternative Pathfinding?&#xA;========================&#xA;&#xA;As noted, practically every pathfinding algorithm&#xA;assumes that costs along every edge are always&#xA;added together.&#xA;&#xA;For quantities that must be multiplied --- such&#xA;as probabilities --- we can use the logarithm&#xA;trick to convert the addition to a multiplication.&#xA;&#xA;However, as noted, the unified cost function&#xA;has quantities that, in order to combine, must&#xA;be added (fees) and multiplied (probabilities).&#xA;&#xA;In essence, every pathfinding algorithm cannot&#xA;use this unified cost function, as they assume&#xA;cost functions that are trivially monoid.&#xA;&#xA;Or is it?&#xA;&#xA;For something like the family of pathfinding&#xA;algorithms Greedy, A\*, and Dijkstra, the only&#xA;operations needed on costs are:&#xA;&#xA;* Addition (actually, a monoidal operation).&#xA;* Comparison.&#xA;&#xA;Rather than &#34;add&#34;, perhaps a better term&#xA;would be to &#34;aggregate&#34; the costs.&#xA;&#xA;    class (Monoid type) where&#xA;         zero :: type&#xA;         `&lt;*&gt;` :: type -&gt; type -&gt; type&#xA;         -- laws where&#xA;         --     forall (a :: type) =&gt; zero &lt;*&gt; a = a&#xA;         --     forall (a :: type) =&gt; a &lt;*&gt; zero = a&#xA;         --     forall (a :: type, b :: type) =&gt; a &lt;*&gt; b = b &lt;*&gt; a&#xA;         --     forall (a :: type, b :: type, c :: type) =&gt; (a &lt;*&gt; b) &lt;*&gt; c = a &lt;*&gt; (b &lt;*&gt; c)&#xA;&#xA;In the above, `&lt;*&gt;` is an &#34;aggregate&#34; operation&#xA;that replaces the simple addition `+` traditionally&#xA;used in pathfinding algorithms.&#xA;For typical numeric types, for example, you could&#xA;derive an addition monoid or a multiplication&#xA;monoid.&#xA;&#xA;We can consider a type that is both `Monoid`&#xA;and `Ord`:&#xA;&#xA;    -- This will be defined by an actual run of the&#xA;    -- pathfinding algorithm.&#xA;    feeBudget :: Integer&#xA;    feeBudget = undefined&#xA;&#xA;    data UnifiedCost = UnifiedCost { fee :: Integer&#xA;                                   , successProbability :: Rational&#xA;                                   }&#xA;&#xA;    -- addition&#xA;    instance (Monoid UnifiedCost) where&#xA;        zero = UnifiedCost { fee = 0&#xA;                           , successProbability = 0&#xA;                           }&#xA;        a &lt;*&gt; b = UnifiedCost { fee = fee a + fee b&#xA;                              , successProbability = successProbability a&#xA;                                                   * successProbability b&#xA;                              }&#xA;&#xA;    -- comparison&#xA;    computeCost :: UnifiedCost -&gt; Rational&#xA;    computeCost c = toRational (fee c)&#xA;                  + ( toRational feeBudget&#xA;                    * (1.0 - successProbability c))&#xA;    instance (Eq UnifiedCost) where&#xA;        a == b = computeCost a == computeCost b&#xA;    instance (Ord UnifiedCost) where&#xA;        compare a b = compare (computeCost a) (computeCost b)&#xA;&#xA;    -- laws where&#xA;    --    forall (a :: UnifiedCost, b :: UnifiedCost) =&gt; a &lt;*&gt; b &gt;= a&#xA;    --    forall (a :: UnifiedCost, b :: UnifiedCost) =&gt; a &lt;*&gt; b &gt;= b&#xA;    -- -- laws could be checked with QuickCheck&#xA;    -- -- though we should ensure `0 &lt;= successProbability &lt;= 1`&#xA;&#xA;That type would work well to replace the type of the&#xA;cost in the Dijkstra-A\*-Greedy family of algortihms;&#xA;they only need comparison and a monoid operation, but&#xA;the actual structure of the cost type is immaterial&#xA;to the algorithm.&#xA;&#xA;In particular, `feeBudget` is constant for an entire&#xA;run of pathfinding algorithms.&#xA;&#xA;The question is whether minimum cost flow algos&#xA;could work with the above limited type.&#xA;I probably need to go actually study those algos.</html></oembed>