ElementsProject / peerswap

MIT License
109 stars 40 forks source link

Ensure that all lnd transactions related to peerswaps are identifiable #254

Open mrfelton opened 12 months ago

mrfelton commented 12 months ago

Peerswap adds a memo to some of the lightning invoices related to swapins that enable easy identification and categorisation of some of the off chain payments related to those swaps. However, labels are not added to the counterpart onchain transactions. This lack of identifying labels for the onchain transactions prevents easy categorisation of the economic activity, and therefore difficulties in accounting and reconciliation.

Additionally, when doing a BTC swapout, there is no way to identify either the onchain receive, or either of the lightning payments as being related to the swap - The onchain receive isn't labeled, and the lightning payments are non-identifiable in lnd. The issue is that peerswaps is paying directly to a payment hash, rather than to a payment request, and as a result payments in lnd's database have no association to the invoices that were paid and therefore no access to the memo from those invoices.

Ideally, we'd be able to use faraday's audit tool to properly classify all of the component parts of a swap,. but this is not currently possible because of the missing correlation points.

For example, the following faraday audit command should allow for classification of all parts of the swaps, but currently only the some are included in the output.

frcli audit --categories '[{"name":"peerswap","off_chain":true,"on_chain":true,"label_patterns":["peerswap.*"]}]'
        {
            "timestamp": "1699623707",
            "on_chain": false,
            "amount": "123450000",
            "credit": true,
            "asset": "BTC",
            "type": "RECEIPT",
            "custom_category": "peerswap", // category added based on regex match on the invoice memo.
            "txid": "42947e46b06b06f3d92bb06204e69a1f393ae5e4649c1c34789823740fec9013",
            "fiat": "0",
            "reference": "bb657f3803e6787fd567d18feb1fbe76e510bb334362afaca629fd6bd7a48872",
            "note": "memo: peerswap btc claim 110x9x0 c50b5d089fbdb913a42ab6ceeaf6e31632e7f4703b3c6afab15b3cf1ec9abe6b",
            "btc_price": {
                "price": "0",
                "price_timestamp": "0",
                "currency": ""
            }
        },

The onchain transactions corresponding to the swaps have the label is set to the default value of external, which is why they are not being categorised as peerswaps by faraday:

lncli listchaintxns
        {
            "tx_hash": "65985c71e87df3cb2becbf84ba13aaf0830de075a474db8dc35dac46ac348a20",
            "amount": "-107750",
            "num_confirmations": 0,
            "block_hash": "",
            "block_height": 0,
            "time_stamp": "1699628927",
            "total_fees": "7750",
            "dest_addresses": [
                "bcrt1qrvhg80uhjwnalywyq0uj3ldhj9pvc6h4tfrhgcy4rzjeemjwx9hsl3kpe3",
                "bcrt1pjahaxxzxhw5rnmjhe2680cppgvpflccqyw3aqz34ph3va4u59s3sgvdy52"
            ],
            "output_details": [
                {
                    "output_type": "SCRIPT_TYPE_WITNESS_V0_SCRIPT_HASH",
                    "address": "bcrt1qrvhg80uhjwnalywyq0uj3ldhj9pvc6h4tfrhgcy4rzjeemjwx9hsl3kpe3",
                    "pk_script": "00201b2e83bf9793a7df91c403f928fdb79142cc6af55a4774609518a59cee4e316f",
                    "output_index": "0",
                    "amount": "100000",
                    "is_our_address": false
                },
                {
                    "output_type": "SCRIPT_TYPE_WITNESS_V1_TAPROOT",
                    "address": "bcrt1pjahaxxzxhw5rnmjhe2680cppgvpflccqyw3aqz34ph3va4u59s3sgvdy52",
                    "pk_script": "5120976fd31846bba839ee57cab477e02143029fe30023a3d00a350de2ced7942c23",
                    "output_index": "1",
                    "amount": "94776263",
                    "is_our_address": true
                }
            ],
            "raw_tx_hex": "020000000001017c20e567d6f5524f0d3b66bd5de392ba5b07266c6b94ea3557d4f22e0276c6720100000000ffffffff02a0860100000000002200201b2e83bf9793a7df91c403f928fdb79142cc6af55a4774609518a59cee4e316fc72ba60500000000225120976fd31846bba839ee57cab477e02143029fe30023a3d00a350de2ced7942c230140f15046a6281bd881b7e41c82667681d0b33ed9f53e42267599bcb2a37327e68f21fd5a2eac439d91595d9da5b051e6a4dc2bf7cc6cc0af65802b0d995b6d87f900000000",
            "label": "external", // this is the default label that lnd applies to the onchain transactions.
            "previous_outpoints": [
                {
                    "outpoint": "72c676022ef2d45735ea946b6c26075bba92e35dbd663b0d4f52f5d667e5207c:1",
                    "is_our_output": true
                }
            ]
        },

For more info, see:

Notes

Currently when performing a swap-out, appropriate descriptions are added to the invoices that the recipient creates. e.g.

fee: peerswap lbtc fee 110x1x1 571e3c0ce9e504e0bda94e01144ed0164021574ce686c719d79488a7e1ac0949

claim: peerswap lbtc claim 110x1x1 571e3c0ce9e504e0bda94e01144ed0164021574ce686c719d79488a7e1ac0949

However, when the payer pays these invoices, it's not paying to the payment request, but instead it's paying directly to the payment hash. See here https://github.com/ElementsProject/peerswap/blob/aef7098f9e57d4490db9799a1680baa1f60715d3/lnd/client.go#L321C26-L323

Notice in the following output from lnd1 listpayments that payment_request is not set in either of the payments that relate to the peerswap, and because of this, the sender doesn't have a reference to the payment requests that it paid:

{
    "payments":  [
        {
            "payment_hash":  "1081dc038215ed6b17600d2ea39ca1b8d4c34b71b1cca9690425b7bea050f12f",
            "value":  "300",
            "creation_date":  "1707069787",
            "fee":  "0",
            "payment_preimage":  "46c11ad2cf5ce2b148fdabf2b680848b65ed5ced3cf862b1ddc2511ed44fb865",
            "value_sat":  "300",
            "value_msat":  "300000",
            "payment_request":  "", // FIXME: payment request should be filled in
            "status":  "SUCCEEDED",
            "fee_sat":  "0",
            "fee_msat":  "0",
            "creation_time_ns":  "1707069787012701513",
            "htlcs":  [...],
            "payment_index":  "1",
            "failure_reason":  "FAILURE_REASON_NONE"
        },
        {
            "payment_hash":  "0dfb1f2904966c249ff61b961e7a2bdcf0a9449bd37dcd3cfe57f7e9c86c50ad",
            "value":  "1000000",
            "creation_date":  "1707070563",
            "fee":  "0",
            "payment_preimage":  "a16c1788fce05a95df697e5e711be4af38889100d962f8225b46ef00268f75fb",
            "value_sat":  "1000000",
            "value_msat":  "1000000000",
            "payment_request":  "", // FIXME: payment request should be filled in
            "status":  "SUCCEEDED",
            "fee_sat":  "0",
            "fee_msat":  "0",
            "creation_time_ns":  "1707070563855858928",
            "htlcs":  [...],
            "payment_index":  "2",
            "failure_reason":  "FAILURE_REASON_NONE"
        }
    ],
    "first_index_offset":  "1",
    "last_index_offset":  "2",
    "total_num_payments":  "0"
}

Suggested fix

Do not use SendToRoute to send the payments here: https://github.com/ElementsProject/peerswap/blob/aef7098f9e57d4490db9799a1680baa1f60715d3/lnd/client.go#L321-L324

Instead, use the SendPaymentV2 RPC and set payment_request in the request. This will ensure that the payments are linked to the peerswap invoices that were paid.

Additionally, when making onchain payments, set a label on the transaction (both in the sender and the recipient's wallets) in order to identify them as peerswaps.

For example, for BTC swaps, when publishing the onchain transaction here: https://github.com/ElementsProject/peerswap/blob/aef7098f9e57d4490db9799a1680baa1f60715d3/lnd/lnd_wallet.go#L203

Set the label parameter when calling the PublishTransaction RPC.

And on the receiving side, use the LabelTransaction RPC to label the incoming onchain transaction once it has been detected.

YusukeShimizu commented 9 months ago

I'd like take up this issue.

YusukeShimizu commented 9 months ago

With https://github.com/ElementsProject/peerswap/pull/281, I have implemented setting the payment_request for lightning payment.

I will address Labeling of onchain transactions separately.

YusukeShimizu commented 8 months ago

With https://github.com/ElementsProject/peerswap/pull/282, I have implemented labeling transactions.