Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lightning integration #1045

Open
8 of 24 tasks
artemii235 opened this issue Aug 16, 2021 · 14 comments
Open
8 of 24 tasks

Lightning integration #1045

artemii235 opened this issue Aug 16, 2021 · 14 comments

Comments

@artemii235
Copy link
Member

artemii235 commented Aug 16, 2021

@shamardy Please post the documentation links, notable libraries, and intermediate milestones reports to this issue comments.

@shamardy
Copy link
Collaborator

LDK/Rust-Lightning is the only good rust lightning network library/crate that exists, there are other libraries that implement LN in Rust but only partially. It also states in the about section that it's designed for integrating lightning with custom features such as our own chain sync/key management/data storage/backup logic.

@shamardy
Copy link
Collaborator

shamardy commented Sep 7, 2021

Update on whether HTLCs are possible on LN.
HTLCs are native to the lightning network as they enable payments between 2 lightning addresses that don't have a direct payment channel open between them. this is done through trustless routing of HTLC payments via a network of channels to open a path for payment between the 2 addresses.
Also, atomic swaps between lightning network and on-chain blockchain addresses already exist and are called submarine swaps. Submarine swaps are mainly used to fund lightning payment channels directly with BTC instead of closing and opening the channel with more funds which cost more in transaction fees. The submarine swaps concept can be extended to swap lightning BTC with other chains and has been implemented before with LTC and BCH.

@shamardy
Copy link
Collaborator

shamardy commented Sep 9, 2021

A few Issues we should take into consideration when Integrating lightning to mm2.

  • In lightning, the parties involved in a transaction must be online during the transaction to prevent fraudulent behavior. If a party goes offline for an extended period of time for any reason an execution fork attack can be carried out. An execution fork can revert a payment channel’s history, potentially causing financial damage to a party that is innocent except for having crashed. To mitigate this watchtowers have been proposed. Watchtowers are third-party services that enable such parties to delegate the cancelation of execution forks on their behalf. I think we should have our own watchtower server/service to prevent such attacks when a user of mm2 goes offline for whatever reason while using the lightning network for a swap.

  • Another issue that is also solved by third-party services is channel capacity. Presumably when a swap using LN and another chain needs to occur both the sender and the receiver need to open a channel (BTC multisig wallet) between them. Opening a channel is costly since it involves an on-chain transaction. This is solved by using multihop payments which involves forwarding payments through channels that already exist if a route can be found between the sender and the receiver. But the problem is that the amount that can be sent is capped by the minimum amount available between the hops that the payment can be routed through, this is where the third-party service comes into play as they provide a channel with big capacity that LN users can open a channel with and can find each other through it. I don't know if we can provide such service or if we integrate with such services so that when an mm2 user opens a lightning channel for the first time uses it providing easy routes for all mm2 users otherwise swaps on LN can be capped to very low amounts.

  • The last issue is not really an issue but a proposal of how to chose between transacting BTC on LN or on-chain. The lightning network fees grow linearly with the amount transacted, so LN swaps are perfect for small swaps. But if the amount is big enough the on-chain transaction fees can be lower than LN fees, this is not taking transaction speed into consideration of course as LN transactions are a lot faster. So when implementing LN fees in mm2 in the future we should take this into consideration.

@shamardy
Copy link
Collaborator

shamardy commented Sep 9, 2021

@artemii235 The next step will be to implement an HTLC PoC on the testnet following this example https://github.com/KomodoPlatform/atomicDEX-API/blob/mm2.1/mm2src/coins/eth/eth_tests.rs#L196 as we discussed.

@shamardy
Copy link
Collaborator

shamardy commented Oct 7, 2021

The following is the best technical book on the lightning network (Maybe the only one) https://github.com/lnbook/lnbook it's equivalent to the "Programming Bitcoin" book but for LN. It's not officially released yet but should be in Jan of 2022. They released the work on progress and now the final production version on Github.

artemii235 pushed a commit that referenced this issue Oct 18, 2021
* impl FeeEstimator, Logger, BroadcasterInterface

* impl Filter for ElectrumClient

* lightning conf + ChainMonitor for electrum

* fix wasm build

* impl keys_manager and channel_manager

* NetGraphMsgHandler, PeerManager, spawn network

* update best block for chainmon and channel manager

* Mock LN events, Persist CM, Background Processing

* 1st version of enable_lightning rpc for test

* refactoring + Error handling

* remove hardcoded lightning conf paramaters

* move LN trait impls for Electrum to seperate file

* enable_lightning test

* move enable_lightning to dispacher_v2

* announce external ip address to LN

* Add node color to configs and request
@artemii235
Copy link
Member Author

We should consider researching the Joule in regards to Lightning web wallet support: https://lightningjoule.com/
https://github.com/joule-labs/joule-extension
cc @ca333 @tonymorony

artemii235 pushed a commit that referenced this issue Dec 14, 2021
* WIP restarting node/read channel_manager from file

* WIP: LN Registry for register_tx & register_output

* update transactions confirmations on node restart

* reconnect to channel peers on node restart

* connect to LN node RPC + WIP lightning ctx

* continued lightning ctx impl for multiple coins

* open_channel RPC

* withdraw to p2wsh addresses + funding tx WIP

* fix zhtlc build

* extract_destinations for p2wsh

* generate/broadcast funding tx (channel opening tx)

* update rust-lightning to v0.0.102

* update rust-lightning to v0.0.103

* fix reconnection to open channels nodes on restart

* save nodes to file fix + order txs to confirm

* add fee param to open_channel RPC + refactors

* use scripthash_get_history to get tx block height

* remove unneeded comments

* WIP:Review fixes, ChannelOpenAmount, UtxoTxBuilder

* WIP: Review fixes, use get_tx_fee for funding tx

* remove WithdrawFee, fix unit test

* WIP: review fixes, use find_output_spend fn

* WIP: review fixes, separate dirs for tickers

* WIP: Review fixes, request_id fix on restart

* WIP: review fixes, LightningCoin

* final fixes: move ln_registry, fix fee with max

* second review fixes

* WIP: review fixes, OpenChannelRequest fix, others

* Review fixes: enable_l2, enable_lightning

* remove lightning from lp_coininit

* use virtual bytes to calculate tx fees

* WIP: more review fixes

* WIP: review fixes, remove block_on

* WIP: review fixes, impl EventHandler trait

* WIP: add validation methods to L2ActivationOps

* Review fixes, add unsigned_funding_txs mutex

* review fixes: NO_SUCH_TRANSACTION_ERROR

* use 'code': -5 to check for tx unconfirmation

* add get_merkle method, use tx index to confirm it
@shamardy
Copy link
Collaborator

shamardy commented Feb 10, 2022

Just opened the lightning payments PR.

After the review process and merging to dev, the next step should be persisting lightning payments and channels history (closed channels) to storage (SQLite) and implementing channels monitors external backup.

Payments history is analogous to transactions history for other coins, as for monitors backup, this is required because lightning channels can't be reconstructed from the seed only unlike other coins so backup to external drive or cloud services is required.

Once both of these functionalities are implemented minimal lightning wallet functionalities can be considered ready.

I updated the above checklist with the upcoming steps. The ordering of these steps can be changed based on priorities.

artemii235 pushed a commit that referenced this issue Feb 28, 2022
* ln-channels PR last comments fixes

* generate_invoice RPC

* update rust-lightning to latest version 0.0.104

* move events related code to ln_events

* get_ln_node_id RPC, handle PaymentReceived event

* WIP: send_payment RPC

* PaymentSent/Failed events, list_payments RPC

* persist network graph, scorer

* move persisting functions to ln_storage

* use async_blocking, PaMutex to fix thread blocking

* list_channels RPC

* PendingHTLCsForwardable Event, mutexes fixes

* Handle SpendableOutputs Event

* remove register funding tx/output as LDK does it

* Fix rust-lightning logs to be same level as mm2

* close_channel RPC

* fixes to spend channel closing outputs

* send a payment by pubkey without invoice (keysend)

* use InvoicePayer for keysend (handles some events)

* Handle PaymentForwarded Event

* my_balance, my_address for lightning coin

* Impl MarketCoinOps related to wallet functionality

* impl MmCoin traits related to wallet functionality

* Reconnection to channels counterparties fixes

* move connection related functions to seperate file

* WIP: Custom channels configuration

* wip custom channels configuration, l2 conf

* Custom channels configuration

* blocking in fee estimate fix, wip: lightning tests

* moved lightning-persister to mm2 to allow for adding test functions

* add get_claimable_balances RPC

* use connect_to_lightning_node to update a channel's node addr if changed

* get_channel_details RPC

* get_payment_details RPC

* payment retries param, use InvoicePayer as BackgroundProcessor event handler

* Remove get_ln_node_id RPC since it's included in enable response

* get confirmation targets for fee estimator from coin config

* move network field from utxo coin to lightning coin

* minor fixes

* add force close option to close_channel RPC + init ln dir

* Simple backup implementation for channels/nodes

* import lightning-background-processor code

* use cfg_native macro where it's possible

* disable LightningCoin in WASM for now

* minor fixes

* review fixes, use more specific types for req/res

* use invoice type for request/response

* impl persist_nodes_addresses on LightningCoin

* create Storage trait for LN and impl for FilesystemPersister

* fix remove test dirs at the end of tests
artemii235 pushed a commit that referenced this issue Apr 28, 2022
* WIP: Channels history in SQL storage

* review fixes: specific types, add serialization tests

* WIP: refactor start_lightning fn

* WIP: continue refactoring start_lightning fn

* WIP: refactoring, add init_channel_manager fn

* WIP: refactoring, ln_p2p

* WIP: refactoring, ln_platform

* Refactor completed

* WIP: use user_channel_id as channel id in rpc calls to avoid using temp id

* Channels in sql WIP: add pending outbound channel to sql

* Channels sql WIP: get channel and add funding_tx

* Channels sql WIP: add funding tx to sql after FundingGenerationReady event

* Channels sql WIP: add closure_reason to sql table

* Channels sql WIP: update channel to closed in sql

* Channels sql WIP: get closed channels in list_channels response

* Channels sql WIP: get closed channel by rpc_id in get_channel_details response

* Channels sql WIP: add closing transaction to sql

* outbound channels history in sql completed

* Payments in sql WIP: add/get payment to/from sql

* Payments in sql completed

* update rust-lightning to v0.0.105

* set manually_accept_inbound_channels to true to be able to add them to sql in the future

* correct calculation of claimed balances

* add destination to payment info

* add description to payment info

* add created/updated at to payment info, wip: list payments by filter

* list_payments_by_filter completed, pagination completed

* list channels by filter for open and closed

* fix wasm build

* part of review fixes

* part of review fixes: save_channel_closing_details function

* review fixes wip: simplify find_watched_output_spend_with_header

* review fixes

* reviw fix for funding_generated_in_block

* fix saving closing tx to db issues if electrums are down

* review fixes: better grouping of SqlStorage trait functions + added descriptions

* review fixes: add get_open_channels_by_filter fn

* review fixes wip: some refactors

* review fixes wip: default_fee_per_kb, refactors

* review fixes: use try_loop_with_sleep macro wip

* review fixes

* remove wasm warnings

* destination can't be None in OutboundPayment

* empty string for description instead of an option

* Review fixes: refactors

* review fixes wip

* wip: more review fixes

* review fixes: inline, refactors

* sql_text_conversion_err, h256_slice_from_row
artemii235 pushed a commit that referenced this issue Jul 28, 2022
#1339)

* remove ok_or_retry_after_sleep_sync! macro

* process_txs_confirmations independent from update_best_block

* use get_tx_height in get_confirmed_registered_txs to prepare for batch requests

* validate_spv_proof refactor wip, spv for lightning wip

* fix test_spv_proof

* remove find_watched_output_spend_with_header

* impl some features of rust-lightning v0.0.106 wip, import code from lightning-persister v0.0.106 and lightning-background-processor v0.0.106 wip

* add inbound channels details to sql db

* remove lightning-persister and lightning-background-processor crates from our codebase and use v0.0.106 crates instead

* remove ok_or_continue macro, use join_all to check for transactions confirmations in batches

* small fixes after testing

* fix fmt

* get confirmed transaction info from spv proof fn

* move get_tx_if_onchain, get_tx_height to rpc_clients

* spv proof refactoring wip

* fix fmt

* spv proof refactor

* break ln_storage.rs to multiple files, break up persister struct into db struct and filesystem struct

* fixes for persisting monitors to back up dir

* fix clippy for windows

* fix some todos

* btc difficulty calculations for spv validation wip

* continued: btc difficulty calculations for spv validation wip, added more test cases

* continued: btc difficulty calculations for spv validation wip, work.rs, storage.rs

* fix wasm, tests

* spv difficulty testnet

* fix some todos

* fixes after merge

* add events abort handlers

* Review fixes wip

* Review fixes wip, log db error in open_channel, workTestVectors.json

* Review fixes, save claiming tx to db after successful broadcasting

* Review fixes wip, use bool without casting, use i64 instead of u64 casting for db operations

* Review fixes wip, #[cfg(target_family = "windows")], refactors

* Review fixes, get tx height by block hash
artemii235 pushed a commit that referenced this issue Oct 27, 2022
* fix some ignored tests

* move connect_to_lightning_node to rpc_command

* move open_channel to rpc_command

* move update_channel to rpc_command

* move list channels rpcs to rpc_command

* move get_channel_details, get_claimable_balances, trusted nodes rpcs to rpc_command

* move close_channel to rpc_command

* move get_payment_details, list_payments_by_filter to rpc_command

* move send_payment to rpc_command

* move the rest of lightning RPCs to rpc_command, use lightning:: prefix for lightning methods

* edit SwapMsg MakerPayment and TakerPayment to allow sending payment instructions to the other side

* create_invoice_for_hash fn, impl other_side_instructions for LightningCoin, copy needed parts of SecretHashAlgo from iris-swap-poc branch

* check connection to nodes before generating route hints, refactors

* fix TakerFee msg to include PaymentDataMsg (lightning invoice to be paid by maker to taker) instead of TakerPayment msg

* Validate invoice received from swap messages wip

* Validate invoice on maker side if maker is lightning coin

* add optional PaymentInstructions parameter to send_maker_payment, send_taker_payment functions

* implement send_taker_payment and send_maker_payment for LightningCoin

* change tx_enum_from_bytes to return none for lightning coin

* Some refactors and rollbacks

* impl more swap methods, do a unit test swap where taker is lightning

* refactor some code by adding payment_hash_from_slice fn

* minor fixes and added more todo for next PR/s

* refactor lightning taker swap test

* more refactors, broadcast_p2p_tx_msg shouldn't work with lightning payments, better todo comments

* add preimage of swap payment to DB after the secret is revealed (claiming funds)

* wip

* Final refactors

* Review fixes: better names for some functions/structs

* Review fixes: some errors fixes, add channels::, nodes::, payments:: namespaces to the RPC methods

* Review fixes: fix some error handling issues

* more review fixes

* review fixes wip: rename SwapTxDataMsg enum variants

* review fixes wip: validate_instructions to return an error instead of None, some refactors

* Review fixes: make TransactionIdentifier::tx_hex not an Option and add is_supported_by_watchers method to SwapOps

* re-add Todo that was removed by merge
artemii235 pushed a commit that referenced this issue Nov 9, 2022
* use task manager to enable lightning

* Move BackgroundProcessor back into LightningCoin now that it gets dropped when the coin is deactivated

* move start_lightning to coins_activation to use LightningRpcTaskHandle to update the enabling progress

* Edit coin deactivation todos

* add one line break ¯\_(ツ)_/¯
@shamardy
Copy link
Collaborator

shamardy commented Nov 10, 2022

After a swap P.O.C with lightning coin as taker was implemented, the next step would be to implement locktimes correctly for lightning. This will let us continue the implementation of maker swaps and swaps refunds for lightning coin. Here are some notes on my research about how swap locktimes can be implemented for lightning:

Assumptions

Payments HTLCs

  • Timelocks are a part of any lightning payment, it allows a lightning node to rollback/refund a payment if the payment recipient doesn't claim it for any reason.
  • This rollback/refund is insured by an exchange of new commitment transactions between every pair of any channel in the payment path/s when a payment is routed through this path.
  • In this new commitment transactions a new HTLC is added for the new payment going through this channel.
  • A delayed spending path is added in the payment HTLC back to the side of the channel that offered the HTLC for the purpose of refund.
  • The other spending path depends on the receiving party knowing the payment preimage, meaning the payment reached it's intended recipient.
  • If a payment is not claimed by the recipient, the parties update the commitment transactions by removing the HTLCs and revoking the old commitment transactions.
  • If a counterparty is offline or refuses to update the commitment transactions for a certain amount of time, the un-updated commitment transaction is broadcasted and the HTLC can be spent on-chain by one of the two paths.
  • This depends on if the payment is claimed or not by the recipient, if claimed, the receiving side of the HTLC will have the preimage.
  • The locktime cltv_expiry_delta in the HTLC is chosen to give the receiving party a window to spend the first path using the preimage.
  • If the locktime has passed, the sending party can spend the delayed spending path on-chain.
  • cltv_expiry_delta was chosen to be large enough (at least 34 blocks) to give the routing parties the chance to appear back online and claim the payment on-chain if the channel between them was closed.

cltv_expiry_delta

  • cltv_expiry_delta is negotiated by the counterparties when opening a channel between them and remains the same value unless the channel is updated. If the channel was updated, the HTLCs in the commitment transactions are not updated with new locktime values of course. Only new HTLCs for new payments use the new value.
  • Common values for cltv_expiry_delta:
    • Most nodes use a cltv_expiry_delta of 40 blocks. We can call this value MEDIAN_HOP_CLTV_EXPIRY_DELTA. This is the value that will be used in all the assumptions to calculate a safe locktime for swap payments.
    • The minimum allowed cltv_expiry_delta value for channels opened with rust-lightning is 42 blocks.
    • The default value that is currently used in mm2 lightning implementation is 72, I guess it can be reduced to 42 to be similar to most nodes.
  • MEDIAN_HOP_CLTV_EXPIRY_DELTA is the locktime for only 1 hop:
    • For a 1 hop payment path consisting of 3 nodes (a sender, a routing node and a receiver) there are 2 channels, meaning there are 2 HTLCs:
      • The first HTLC is between the sender and the routing node with a cltv_expiry_delta that is equal to the MEDIAN_HOP_CLTV_EXPIRY_DELTA
      • The second HTLC is related to the last hop and has a different cltv called final_cltv_expiry. final_cltv_expiry must be greater than a value determined by the receiving node in the invoice. This value is called min_final_cltv_expiry.
      • min_final_cltv_expiry has a minimum allowed value of 24 blocks in rust-lightning. This is the value that is currently used in swaps implementations.
      • The final_cltv_expiry is increased by a random value to obfuscate who is receiving this payment to the routing nodes, this is required since lightning payments should be private. This obfuscating is done by a concept called shadow routing, this consists of adding a cltv value of a random chosen real route after the last hop consisting of 1 to 3 more hops.
      • final_cltv_expiry = min_final_cltv_expiry + shadow_route_cltv_expiry or for the maximum value that we will use for swap locktimes calculations is min_final_cltv_expiry + 3 * MEDIAN_HOP_CLTV_EXPIRY_DELTA
      • In general, the median total payment expiry time for a multi hop payment can be calculated as following:
        median_total_cltv_expiry = (no_of_hops + 3) * MEDIAN_HOP_CLTV_EXPIRY_DELTA + min_final_cltv_expiry
      • Here are a few examples of routing to demonstrate the above.

Maker Swap Locktime if LightningCoin is Taker

  • A good maximum number of hops needs to be determined to calculate a safe Maker Swap Locktime.
  • In my opinion 3 hops are good enough given that users should have channels open to good connected nodes. If there is no route between the 2 nodes making the swap their orders shouldn't be matched anyways.
  • For a maximum of 3 hops the median_total_cltv_expiry for the taker payment will be 264 blocks. This means that the maker payment in the other coin should have a locktime of 528 blocks which is about 3 days and 16 hours. If something goes wrong in the swap the maker will need a lot of time to refund his payment, by reducing the number of hops for swap payments to 3 we reduce the probability of the lightning payment swap to fail too. We can reduce the maker locktime by not making it double the taker locktime in this case but I am not sure if this is the right call. What do you think @artemii235?

Taker Swap Locktime if LightningCoin is Maker

  • Current used locktimes for swaps in mm2 can be used for taker non-lightning payments Locktimes if LightningCoin is Maker. The only value of importance here for the taker is min_final_cltv_expiry which should be double the taker payment locktime.

@artemii235
Copy link
Member Author

artemii235 commented Nov 11, 2022

@shamardy
Thanks for very detailed research! 🙂

The median_total_cltv_expiry for the maker payment will also be 264 blocks. In this case the taker swap locktime will be 22 hours. I believe this is acceptable.

Yes, this seems acceptable. Though,

This means that the maker payment in the other coin should have a locktime of 528 blocks which is about 3 days and 16 hours.

is a bit too much 🙂

We can reduce the maker locktime by not making it double the taker locktime in this case but I am not sure if this is the right call.

We can try it - with such a long lock duration, even 1,5x will give taker enough time to act even if his payment is spent right before locktime expiration.

Also, a couple of questions:
examples demonstrate the node having cltv_expiry_delta=10. Why rust-lightning uses 42 as default value and why it can't be decreased? Lowering it to minimum recommended 34 value could give us a noticeable outcome.

(no_of_hops + 3) - I couldn't find an explanation on why 3 is added to number of hops? 🙂 Can this constant be decreased?

@shamardy
Copy link
Collaborator

shamardy commented Nov 11, 2022

The median_total_cltv_expiry for the maker payment will also be 264 blocks. In this case the taker swap locktime will be 22 hours. I believe this is acceptable.

Yes, this seems acceptable. Though,

First, Just adding a note about this to not forget :)
The taker has to make sure that the final_cltv_expiry (last hop cltv) for the maker lightning payment is at least double his (other coin) swap locktime. I will add this info to the above research comment to have a complete picture in one comment.

(no_of_hops + 3) - I couldn't find an explanation on why 3 is added to number of hops? 🙂 Can this constant be decreased?

The 3 is related to the maximum shadow route hops. As shown by the below quote from the my original comment.

The final_cltv_expiry is increased by a random value to obfuscate who is receiving this payment to the routing nodes, this is required since lightning payments should be private. This obfuscating is done by a concept called shadow routing, this consists of adding a cltv value of a random chosen real route after the last hop consisting of 1 to 3 more hops.

I believe it can be decreased, or even be zero in some cases :)
The max_total_cltv_expiry_delta that can be specified in the route parameters when finding a route for the payment can be set to a value of no_of_hops * MEDIAN_HOP_CLTV_EXPIRY_DELTA + min_final_cltv_expiry which in case of 3 hops equal to 24 hours / 1 day. If the route/path found has a total cltv of exactly 24 hours (path_total_cltv_expiry_delta), no shadow route will be added. If path_total_cltv_expiry_delta is less than 24 hours then a cltv less than or equal to the remainder from 24 hours will be added. In this case maker locktime can be 1.5 days if 1.5x is used. In general we can specify any constant maker locktime we want and the taker will have to find a route that matches the constraints, but for 3 hops as stated 1.5 days can be a good compromise, if the locktime is increased more routes can be found.

examples demonstrate the node having cltv_expiry_delta=10.

This is for demonstration purposes only.

Why rust-lightning uses 42 as default value and why it can't be decreased? Lowering it to minimum recommended 34 value could give us a noticeable outcome.

Most nodes use cltv_expiry_delta = 40 in their configs. It can be verified by checking the channels of the most connected nodes here, 40 and 144are the most used numbers. I believe 40 is chosen because it's the default number in LND sample config, it gives a bit more safety than the recommended minimum of 34. I am not sure why 42 was chosen by rust-lightning, they maybe rounded the number of hours to 7 hours, or added 2 blocks to give the node better safety against chain reorganizations / transaction to appear on-chain. Also 42 is the answer to life the universe and everything 😁

@shamardy
Copy link
Collaborator

First, Just adding a note about this to not forget :)
The maker has to make sure that the final_cltv_expiry (last hop cltv) is less than the taker swap locktime (Assumed 22 hours for now). I will add this info to the above #1045 (comment) to have a complete picture in one comment.

final_cltv_expiry (last hop cltv) should be more than taker swap locktime (at least double like other swaps to give the taker enough time to claim the lightning payment), not less. I miscalculated this, will update this in both comments now. Taker swap locktime (for other non-lightning coins) when Maker is lightning can be just the current implemented swap locktimes in mm2, not 22 hours.

@shamardy
Copy link
Collaborator

This is a diagram to demonstrate swap locktimes if taker is LightningCoin as explained in #1045 (comment) #1045 (comment)
Lightning taker locktimes
This is another diagram to demonstrate swap locktimes if maker is LightningCoin as explained in #1045 (comment) #1045 (comment)
Lightning maker locktimes

@shamardy
Copy link
Collaborator

shamardy commented Dec 1, 2022

@artemii235 In this comment, I would like to propose a solution to how lightning taker fees can be implemented in AtomicDEX so that we can discuss this solution before proceeding with implementing this part of the lightning network integration.

Problems

  • To receive a lightning fee from a taker through the lightning network, Komodo would need to run its own lightning node that the taker can pay the fee to. Which brings about the following problems:
    • Centralization: Komodo's lightning node will be a single point of failure for lightning swaps.
    • Security: Lightning nodes are hot wallets.
  • Lightning payments are private in nature, there is no single source of truth like how it is for on-chain transactions. Because of this, a method of verification is needed for the maker to verify that the taker has paid the fee.

Proposed Solution

  • We can avoid running a lightning node for the fees altogether and make the taker pay the fee on-chain.
    • This solves the centralization, security and verification problems.
    • But this also defeats the purpose of integrating the lightning network by increasing the fees and swap times.
    • This solution can be used as a backup to the next solution that requires running a lightning node for the fees, if the fees node is down for any reason, trading can resume using on-chain fees until the node is operational again.
  • A lightning node for fees is used.
    • lightning offers are used to solve the verification problem. Lightning offers will be described in details in the next section.
    • Phantom Nodes are used to solve the single point of failure problem. The article linked provides the necessary information about phantom nodes. I still need to do more research on this topic to be sure that it completely fits the requirements.
    • Validating Lightning Signer is used to solve the hot wallet problem. Merchant policy control can be used to ensure that no funds can be sent from the fees lightning node without external signing. I still need to do more research on this topic to be sure that it completely fits the requirements.

Lightning offers

  • Lightning offers are mostly implemented in core lightning and currently being implemented in rust-lightning.
  • It shouldn't take long for offers to be an official lightning bolt (it's next in line actually, currently there are 11 official bolts, offers is bolt12), which means all lightning node implementations should implement it.
  • An offer by komodo's lightning node for fees will be hardcoded similar to the dex fee address public key. An offer can live forever unlike invoices which require an expiration timestamp to be set.
  • The taker should start with an invoice request to pay the fees by paying the invoice that he will receive in response to this request. This request is routed through the lightning network to reach the fees lightning node.
  • In the invoice request, the taker should set invreq_payer_note to the swap's secret hash.
  • The fees lightning node will send the taker through the lightning network a signed invoice, it will have the same invreq_payer_note set by the taker which is equal to the swap's secret hash.
  • The taker will pay the fee by paying the invoice, receiving the preimage for the invoice payment hash.
  • The taker will send the maker the signed invoice and the preimage in the TakerFee msg.
  • To verify that the taker paid the fee, the maker will verify the following:
    • The invoice is signed by the fees lightning node public key, this is the node's public key not the dex fee address public key. The node's public key should be hardcoded in mm2 code too since it doesn't change.
    • The signed invoice invreq_payer_note field is equal to the swap's secret hash.
    • The hash of the preimage is equal to the invoice payment hash.

@shamardy shamardy mentioned this issue Jan 10, 2023
8 tasks
artemii235 pushed a commit that referenced this issue Jan 13, 2023
#1045

* lightning refunds wip: add is_auto_refundable, wait_for_htlc_refund SwapOps functions

* lightning refunds wip: move fail_htlc_backwards to the right place

* lightning refunds wip: add update_payment_status_in_db to LightningDB trait

* add update_payment_to_received_in_db method to LightningDB

* add update_payment_to_sent_in_db method to LightningDB

* change add_or_update_payment_in_db to add_payment_to_db, remove payment secret from payment info and db

* edit docs/notes related to fail_htlc_backwards

* fix typo: rename if_my_payment_spent_args to if_my_payment_sent_args

* impl check_if_my_payment_sent for LightningCoin

* add TakerPaymentInstructionsReceived to TAKER_SUCCESS_EVENTS, MakerPaymentInstructionsReceived to MAKER_SUCCESS_EVENTS

* implemented recover_funds for lightning, revised lightning swap restart, recreate_swap_data

* Remove unneeded todos

* review fixes wip: add MakerSwapOps and TakerSwapOps

* review fixes wip: update deny.toml

* review fixes wip: revert deny.toml changes

* review fixes wip: add on_start/success trait methods to MakerSwapOps/TakerSwapOps

* review fixes wip: fix wait_for_htlc_refund to not return TransactionFut

* review fixes wip: add with_preimage, with_status methods to PaymentInfo impl

* review fixes wip: use owned_named_params for insert_payment_sql

* first review fixes complete: use owned_named_params for insert_channel_sql, used params macro where applicable

* second review fixes wip: use repeatable in wait_for_htlc_refund implementation for LightningCoin

* second review fixes wip: remove white spaces in recover_funds, fix is_auto_refundable in maker_swap's recover_funds

* second review fixes wip: rename MakerSwapOps/TakerSwapOps to TakerSwapMakerCoin/MakerSwapTakerCoin

* second review fixes wip: Add TakerSwapCommand::PrepareForTakerPaymentRefund, TakerSwapCommand::FinalizeTakerPaymentRefund

* second review fixes: Add MakerSwapCommand::PrepareForMakerPaymentRefund, MakerSwapCommand::FinalizeMakerPaymentRefund

* more review fixes
@shamardy
Copy link
Collaborator

@smk762 after this PR #1592, new events that should be documented were added to MAKER_SUCCESS_EVENTS, MAKER_ERROR_EVENTS, TAKER_SUCCESS_EVENTS, TAKER_ERROR_EVENTS. These events are:

  • MakerPaymentInstructionsReceived added to MAKER_SUCCESS_EVENTS: This event is triggered alongside TakerFeeValidated event (it's before it in order, if both are successful, both are triggered. If one of them fails TakerFeeValidateFailed is triggered instead). It indicates that maker received inside the TakerFee swap message instructions on how to send their payment and validated these instructions successfully. For protocols other than lightning the event success depends on taker fee validation success since no payment instructions are sent.
  • TakerPaymentInstructionsReceived added to TAKER_SUCCESS_EVENTS: This event is triggered alongside MakerPaymentReceived, MakerPaymentWaitConfirmStarted events (it's before them in order, if all are successful, all are triggered. If one of them fails MakerPaymentValidateFailed is triggered instead). It indicates that taker received inside the MakerPayment swap message instructions on how to send their payment and validated these instructions successfully. For protocols other than lightning the event success depends on maker payment validation success since no payment instructions are sent.
  • MakerPaymentRefundStarted added to MAKER_ERROR_EVENTS: This event is triggered after MakerPaymentWaitRefundStarted event. It indicates that the refund process for maker payment has started successfully and any process required before it was successful.
  • TakerPaymentRefundStarted added to TAKER_ERROR_EVENTS: This event is triggered after TakerPaymentWaitRefundStarted event. It indicates that the refund process for taker payment has started successfully and any process required before it was successful.
  • MakerPaymentRefundFinished added to MAKER_ERROR_EVENTS: This event is triggered after MakerPaymentRefunded event. It indicates that any process needed after maker payment was refunded was successful.
  • TakerPaymentRefundFinished added to TAKER_ERROR_EVENTS: This event is triggered after TakerPaymentRefunded event. It indicates that any process needed after taker payment was refunded was successful.

Full list of success and error events after this change

Maker success events

"success_events": [
    "Started",
    "Negotiated",
    "MakerPaymentInstructionsReceived",
    "TakerFeeValidated",
    "MakerPaymentSent",
    "TakerPaymentReceived",
    "TakerPaymentWaitConfirmStarted",
    "TakerPaymentValidatedAndConfirmed",
    "TakerPaymentSpent",
    "TakerPaymentSpendConfirmStarted",
    "TakerPaymentSpendConfirmed",
    "Finished",
]

Taker success events

"success_events": [
    "Started",
    "Negotiated",
    "TakerFeeSent",
    "TakerPaymentInstructionsReceived",
    "MakerPaymentReceived",
    "MakerPaymentWaitConfirmStarted",
    "MakerPaymentValidatedAndConfirmed",
    "TakerPaymentSent",
    "TakerPaymentSpent",
    "MakerPaymentSpent",
    "Finished",
]

Maker error events

"error_events": [
    "StartFailed",
    "NegotiateFailed",
    "TakerFeeValidateFailed",
    "MakerPaymentTransactionFailed",
    "MakerPaymentDataSendFailed",
    "MakerPaymentWaitConfirmFailed",
    "TakerPaymentValidateFailed",
    "TakerPaymentWaitConfirmFailed",
    "TakerPaymentSpendFailed",
    "TakerPaymentSpendConfirmFailed",
    "MakerPaymentWaitRefundStarted",
    "MakerPaymentRefundStarted",
    "MakerPaymentRefunded",
    "MakerPaymentRefundFailed",
    "MakerPaymentRefundFinished",
]

Taker error events

"error_events": [
    "StartFailed",
    "NegotiateFailed",
    "TakerFeeSendFailed",
    "MakerPaymentValidateFailed",
    "MakerPaymentWaitConfirmFailed",
    "TakerPaymentTransactionFailed",
    "TakerPaymentWaitConfirmFailed",
    "TakerPaymentDataSendFailed",
    "TakerPaymentWaitForSpendFailed",
    "MakerPaymentSpendFailed",
    "TakerPaymentWaitRefundStarted",
    "TakerPaymentRefundStarted",
    "TakerPaymentRefunded",
    "TakerPaymentRefundFailed",
    "TakerPaymentRefundFinished",
]

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

No branches or pull requests

3 participants