Good morning list,
As it happens, I was considering about JIT-routing by Rene Pickhardt.
And I notice that Rene has been proposing about a "fee-free rebalance" in order
to better support JIT-routing.
And I have been thinking about this "fee-free rebalance" proposal.
As a review, JIT-routing allows a sort of "semi-local multipart payment".
The intuition is, that a forwarding node has better information about local
channel balances, than the source node has information about remote channel
balances along the route.
What JIT-routing means, more specifically, is to perform channel rebalance
operations "just-in-time" for a forwarding request.
The forwarding node, knows exactly the balances in its channels, and thus can
determine how best to deliver the required funds to the next hop in the onion.
So I considered, the simplest case of useful JIT-routing.
Specifically, suppose that there exist three nodes on the network, forming a
tiny cyclic superhub of three members.
Let us call them ZmnSCPxj, YAijbOJA, and Rene.
Let us suppose that they all have channels to each other, of total capacity 0.1
BTC, and with each channel perfectly balanced at 0.05 BTC to each side.
Let us suppose there is a channel reserve of 0.01 BTC for each channel.
Suppose ZmnSCPxj receives a forwarding request, with the next hop being 0.06BTC
to YAijbOJA.
As the useable capacity (minus channel reserve) is only 0.04BTC, ZmnSCPxj
cannot facilitate this forwarding request.
Under JIT-Routing, what ZmnSCPxj does, is to route 0.02 BTC from
ZmnSCPxj->Rene->YAijbOJA->ZmnSCPxj, i.e. a rebalance of capacity from the
ZmnSCPxj<->Rene channel, to the ZmnSCPxj<->YAijbOJA channel.
But under the current network, this would require a fee for this rebalancing
attempt.
Now, ZmnSCPxj could argue with YAijbOJA and show the forwarding request of 0.06
BTC to YAijbOJA.
As YAijbOJA also knows the current state of the ZmnSCPxj<->YAijbOJA channel, it
knows this forwarding request cannot push through currently, unless the
rebalance completes.
This is sufficient to convince YAijbOJA to waive its fee for transporting from
the Rene<->YAijbOJA channel to the ZmnSCPxj<->YAijbOJA channel, since otherwise
it would not gain the fee (or final payment if it is the payment termination
point) for the ZmnSCPxj->YAijbOJA forward.
However, Rene cannot be so convinced.
After all, both ZmnSCPxj and YAijbOJA are strangely-named nodes, unlike Rene
whose name is actually pronounceable.
In particular, the forwarding packet cannot even be read by Rene; and in any
case, why should Rene waive the fee when it cannot benefit by doing so?
YAijbOJA can benefit since by enabling the forward request from
ZmnSCPxj->YAijbOJA, it could gain an even larger fee from forwarding onwards
(assuming the same base fee, and a proportional fee, the larger forwarding from
ZmnSCPxj->YAijbOJA of 0.06 BTC will lead to a larger proportional fee compared
to the YAijbOJA->ZmnSCPxj forward of 0.02 BTC).
Thus, it seems to me that we can argue for a fee-free forwarding, but only for
the last hop in the rebalance.
Now, in particular, note that YAijbOJA should only be willing to waive the fee,
if ZmnSCPxj will actually hand it a 0.06 BTC HTLC for ZmnSCPxj->YAijbOJA, in
exchange for resolving the 0.02 BTC HTLC for YAijbOJA->ZmnSCPxj.
So I propose the following constructions below for this.
We need an HTLC-dependent HTLC construction.
What this means is, that YAijbOJA will offer a construction, which requires
that ZmnSCPxj reveals a preimage.
Onchain, when ZmnSCPxj reveals this preimage, it is forced to claim this into
an HTLC, which represents the original forwarding attempt from
ZmnSCPxj->YAijbOJA.
This is needed to assure YAijbOJA that it will have an opportunity to earn fees
later if it waives the fee for forwarding to ZmnSCPxj first.
So let us be more precise, and say:
orig_preimage = preimage for the original 0.06BTC forwarding from
ZmnSCPxj->YAijbOJA.
orig_hash = h(orig_preimage)
rebal_preimage = preimage for the rebalance from
ZmnSCPxj->Rene->YAijbOJA->ZmnSCPxj.
rebal_hash = h(rebal_preimage)
1. When the rebalance onion reaches YAijbOJA from Rene, YAijbOJA opens the
onion packet.
Included in this packet is a short note from ZmnSCPxj explaining that there
is an "original onion" that would forward 0.06 BTC to YAijbOJA, but given the
current channel state, ZmnSCPxj cannot forward it unless this rebalance pushes
through, so can YAijbOJA waive its fee?
2. Then, YAijbOJA requests for the original onion from ZmnSCPxj.
This is safe for ZmnSCPxj to send, since there is no HTLC from
ZmnSCPxj->YAijbOJA yet.
YAijbOJA is not incentivized to forward this yet since it has no incoming
HTLC, meaning it would lose money if it forwarded it immediately.
3. YAijbOJA validates the original onion.
If it decrypts correctly, and forwards with sufficient fee from ZmnSCPxj to
YAijbOJA so that it beats the fee it is being asked to waive, or if YAijbOJA is
the final payee, then it allows to continue the protocol.
4. YAijbOJA and ZmnSCPxj agree to create a 0.06 BTC output on both commitment
transactions to the below SCRIPT.
0.02 BTC is gotten from YAijbOJA main output, and 0.04 BTC from ZmnSCPxj
main output, to funds this contract.
OP_DUP OP_HASH160 <RIPEMD(SHA256(revocationpubkey))> OP_EQUAL
OP_IF
OP_CHECKSIG
OP_ELSE
OP_SIZE 32 OP_EQUAL
OP_IF
# hash branch
OP_HASH160 <RIPEMD(rebal_hash)> OP_EQUALVERIFY
OP_ELSE
# timelock branch
OP_DROP
<cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
OP_ENDIF
2 <ZmnSCPxj_htlcpubkey> <YAijbOJA_htlcpubkey> 2 OP_CHECKMULTISIG
OP_ENDIF
5. Note that the commitment transactions **cannot** be signed **yet**!
Both YAijbOJA first need to exchange signatures for two special
transactions, HTLC-waivefee-timeout and HTLC-waivefee-success.
6. HTLC-waivefee-timeout takes the above output and spends it using the
timelock branch.
Its `nLockTime` is thus equal to `cltv_expiry`.
Its witness is `<ZmnSCPxj_waivefee_timeout_signature>
<YAijbOJA_waivefee_timeout_signature> 0`.
There are two versions, depending on which commitment transaction (that of
ZmnSCPxj, or that of YAijbOJA) is being spent from.
Signatures for both versions must be exchanged.
It has two outputs, 0.04 going to ZmnSCPxj (revocable if from ZmnSCPxj
commitment) and 0.02 going to YAijbOJA (revocable if from YAijbOJA commitment).
7. HTLC-waivefee-success takes te above output and spends it using the hash
branch.
Its witness is `<ZmnSCPxj_waivefee_success_signature>
<YAijbOJA_waivefee_success_signature> <rebal_preimage>`.
Again two version depending on which commitment transaction is spent.
Signatures for both versions must be exchanged.
It pays out to a single output, with script "Offered HTLC Outputs" /
"Received HTLC Outputs" in existing BOLT#3, using the `orig_hash` as the
`payment_hash`.
8. After exchanging the signatures for the above transactions, ZmnSCPxj and
YAijbOJA can now exchange signatures for the commitment transactions as usual
using `commitment_signed`, then `revoke_and_ack`.
9. When ZmnSCPxj fulfills the rebalancing HTLC, this puts the `orig_hash`
HTLCs directly into the commitment transactions.
This lets YAijbOJA claim the rebaancing HTLC from Rene, and forward
normally onwards.
If the `orig_hash` payment is later failed, then the entire 0.06 BTC amount
is returned to ZmnSCPxj, since it has already transferred 0.02 BTC from its
ZmnSCPxj<->Rene channel.
--
Another observation I make, is the consideration of the use of Channel
Factories.
In particular, JIT-routing can instead use a factory-level operation to
reorganize channel funds.
ZmnSCPxj can request a factory channel reorganization to move some funds from
the ZmnSCPxj<->Rene channel to the ZmnSCPxj<->YAijbOJA channel.
This has the same effect, i.e. it allows a forwarding attempt to push through,
that would not be possible without the factory-level channel reorganization.
Further, assuming only ZmnSCPxj, YAijbOJA, and Rene are in the channel factory,
then it is the same: all three need to be online in order for the JIT-routing
to work.
But I observed above that, in a channel rebalance using current channels
(without factories) Rene cannot be convinced to waive the fee.
This points to the next observation:
1. Channel rebalances really should be free, as we might imagine channel
factory reorganizations to be.
OR
2. Factory-level channel reorganizations should charge a fee, paid by nodes
that want to remove capacity, to the nodes whose channel is reduced by the
removed capacity.
i.e. in the Channel Factory case, the factory-level channel reorganization
should make Rene demand a fee from ZmnSCPxj in exchange for agreeing to the
reorganization, because of the loss of capacity in the ZmnSCPxj<->Rene channel.
I suspect the second is true: the reduced capacity in the ZmnSCPxj<->Rene
channel means that ZmnSCPxj is less likely to successfully route to Rene, due
to the reduce capacity to Rene.
Thus, Rene may be disincentivized to allow the transfer of capacity *away* from
ZmnSCPxj<->Rene channel without recompense.
--
Another thought is the below.
Suppose that in fact, YAijbOJA thinks that the capacity of the
ZmnSCPxj<->YAijbOJA channel is too high on the YAijbOJA side.
And similarly, suppose Rene thinks the capacity of the Rene<->YAijbOJA channel
is too high on the Rene side.
Thus, both YAijbOJA and Rene would welcome the ZmnSCPxj proposal to rebalance,
as it moves the capacities.
It may be that they are so welcoming of this proposal, that they are willing to
waive the fee for the rebalance.
I observe that many have already proposed "negative routing fees" in order to
support rebalancing of their channels.
I also observe that routing fees are the cost used in pathfinding algorithms,
and most pathfinding algorithms do not behave well with negative costs.
But it is perfectly fine to use ***zero*** routing fees, I think.
For those pathfinding algorithms that require nonzero cost, it is often easy to
add a very tiny minimal cost to edges that have 0 cost.
Indeed, this is often practical to add a tiny cost to every edge traversed,
whether the edge is nominally 0-cost or not.
For example, C-Lightning does this, since routes with the same fees are not
equal if one route has more nodes --- more nodes are less likely to succeed in
routing.
So our software today, should in practice already be quite fine with handling 0
routing fees, if the node wishes to rebalance its channel.
I also observe, from a skim of BOLT #7, the spec does ***NOT*** have any
verbiage to the effect "`fee_base_msat` MUST be non-zero" or
"`fee_proportional_millionths` MUST be non-zero".
Thus our spec implicitly allows, by not specifying otherwise, 0 routing fees,
already, today.
Thus I think we can fix multiple problems with one solution ---
* Instead of ***negative*** routing fees, use ***zero*** routing fees if a
channel has too much capacity on our side.
* Such ***zero*** routing fees also implicitly implement fee-free rebalancing,
to support JIT-routing.
This requires ***no spec change***, which is a tremendously good property that
JIT-routing has.
Regards,
ZmnSCPxj
_______________________________________________
Lightning-dev mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev