Good morning Rene and Ariel,

> Hey everyone, 
> I am glad the suggestion is being picked up. At this time I want to respond 
> to two of the concerns that have been thrown in. I have some other comments 
> and ideas but would like to hold them back so that we can have more people 
> joining the discussion without bias also this mail will already be quite long.
> ZmnSCPxj suggested to introduce a `success_rate` for JIT routing. While this 
> success_rate can obviously only be estimated or configured I would advice 
> against including this to the protocol. As I mentioned before I suggested to 
> include JIT Routing as a MAY Recommendation so it is up to the node to decide 
> if it cannot earn `offered_fee_amount` to engage in the JIT-rebalancing 
> operation.

I think it is beyond the scope of the protocol specs to specify this.
However, we should remember that it is not the protocol specs that is running 
on the actual network, but actual implementations.
Thus the exact rule may need discussion nevertheless, as it may affect the 
ability to attack actual implementations on the network.

> A node operator might be willing in general to to pay a fee for rebalancing 
> even if there is not an outstanding routing event taking place. So even while 
> `rebalancing_fee_amount` > `offered_fee_amount` the node could see the 
> offered_fee_amount as a discount for the planned rebalancing amount. We don't 
> know that and I honestly believe that the protocol should not make economical 
> decisions for the node. In any case rebalancing will overall increase the 
> likelihood for successful routing but it makes sense to defer the rebalancing 
> operation to a moment in which the liquidity is actually needed. 
> Regarding Ariels suggestion about reusing the payment hash with JIT Routing I 
> have some more thoughts:
> Reusing the payment hash indeed seems like a good idea. However it produces 
> some technical issues which in my opinion can all be mitigated. it is just a 
> question with these challenges if it is worthwhile doing it?
> I have drawn several situations and tried to construct an example in which 
> using the same payment hash for the JIT-rebalancing would result in a severe 
> problem with the payment process in the sense that it would be compromised or 
> somebody could steal funds. It could however be a privacy issue as more nodes 
> are being aware of the same payment (but that is also the case with base-AMP) 

This would be fixable when we switch to points and scalars (from hashes and 
preimages) and enable route decorrelation, just as it would improve base-AMP.

> I was not able to construct such a situation (under the assumption that the 
> rebalancing amount does not exceed the original payment amount). My feeling 
> (though I have not done this yet) is that one should be able to proof that 
> taking the same payment hash would always work and in fact create a situation 
> in which at least the rebalancing only takes place if the entire payment was 
> routed successfully. 
> Assuming someone will be able to proof that using the same payment hash for 
> JIT Routing is not an issue we still run into another problem (which I 
> believe can be fixed with another MUST rule but comes with quite some 
> implementation overhead.)
> The deadlock problem when doing JIT Routing with the same payment hash: 
> When using the same payment hash there will be two htlc's (potentially of 
> different amounts) in opposing directions on the same channel (or in the lnd 
> case maybe between separate channels between the same two peers). Unluckily 
> without a novel rule this can produce a deadlock. 
> As an example take the situation from my initial email with an additional 
> recipient R1: 
>   100 / 110     80 / 200      150/180
> S ----------> B --------> R ----------> R1
>               \         /
>         80/200  \     /  100/200
>                   \ / 
>                    T
> Meaning we have the following channels:
> S ---> B capacity: 110   A funds: 100  B funds:  10
> B ---> R capacity: 200   B funds:  80  R funds: 120
> B ---> T capacity: 200   B funds:  80  T funds: 120
> T ---> R capacity: 200   T funds: 100  R funds: 100 
> R ---> R1 capacity: 180   R funds: 150  R1 funds: 30 
> neglecting fees the following htlcs would be offered
> 1.) S-->B amount: 90
> 2.) B-->T amount:50
> 3.) T-->R amount:50
> 4.) R-->B amount: 50
> 5.) B-->R amount: 90 (difficult to set up before 4. settles)
> 6.) R-->R1 amount: 90 
> while 1,5 and 6 are the original path 2,3,4 are the JIT rebalancing. 
> We see that in this situation using the same preimage results in a problem. 
> Since the rebalancing is not settled R will not accept the 5th htlc (B--->R 
> amount: 90) as there is not enough liquidity on B's side producing a deadlock
> However since the same payment hash is used it is save to combine the 4th and 
> 5th htlc to have the following situation: 
> 1.) S-->B amount: 90
> 2.) B-->T amount:50
> 3.) T-->R amount:50
> 4.) R-->B will be removed or settled or replaced by the 5th htlcs with a 
> different amount (90 - 50)
> 5.) B-->R amount: 40 
> 6.) R-->R1 amount: 90 
> Note that while theoretically it seems tempting to just have two htlc outputs 
> as the second node could always claim the htlc if the first claims theirs. 
> However this will not work onchain as potentially more funds are spend than 
> exist.
> Therefor we need a MUST-rule to fix the deadlock problem (which could 
> probably also be formulated in a symmetric way): 
> If a node N offers an htlc to a partner with an amount x from whom the node 
> already received an htlc y (where y is smaller than x) the nodes must create 
> a new channel state discarding the old htlc but having a new offer from N 
> with the amount x-y.

Or more clearly:

* Given two nodes A and B:
  * If B has already offered an HTLC with hash `h` and value `y`, AND A offers 
an HTLC with hash `h` and value `x` such that `x > y`:
    * The previous HTLC from B to A with value `y` is replaced with a new HTLC 
from A to B with value `x - y`.
    * The value owned by A is deducted by `x - y` instead of `x`.
      * Normal checks for capacity in A side should check `x - y`.
    * The value `y` is returned to ownership of B.
    * B performs forwarding normally with the value `x` as the amount to 
continue forwarding, or as payment if it is the final node.

Note that the overall effect on the route would be as if there were a "local 
bass amplifier" from the node that performs the JIT-routing.
It also is nearer to a "JIT routing" than a "JIT rebalancing".

This also complicates the database needed to chain HTLCs together (particularly 
in c-lightning).
We would have to connect the outgoing HTLC to two incoming HTLCs.

However this probably needs a feature bit.
If one side does not support this feature, it will `error` in response to an 
attempt to forward where the available capacity is greater than the available 
This `error` will cause the channel to be closed unilaterally.

In a decorrelation world, this will still work, but `B` now knows that a JIT 
local bass amplifier was done.

> This decreases the liquidity bound in the routing process, enables for a 
> critical channel to be rebalanced several times during several JIT operations 
> and keeps the onchain footprint low as there are less htlc outputs. 
> Also as mentioned above it seems crucial that the rebalancing amount must not 
> exceed the original payment amount if the payment hash is being reused. 
> Imagine there was no R1 and R was actually the final destination and B 
> decides to rebalance an amount larger than necessary (which could not happen 
> in our setup). R could release the preimage before setting up the final htlc 
> from R back to B to fulfill the rebalancing request. This could also happen 
> if T was the final recipient (which R would not now!)

But what about for invoices with no particular amount?
Since the invoice has no particular amount, the recipient will assume that any 
offered value is correct.

So suppose we have that `R` is the recipient.
In that case, the rebalancing attempt by B looks like a small offer.
Since `R` knows the preimage, it can grab the value.

Note in particular that lnd is known to have this behavior (I know the 
preimage, I will take the coins and ignore the onion packet).
In this case it would be loss of lnd to do so, since it will get the smaller 
rebalance value rather than the full payment to be forwarded.
Good thing we are both c-lightning developers.

Lightning-dev mailing list

Reply via email to