Skip to content

[bug]: Unexpected Payment Success: Invoicing Sats but Paying with Assets #1239

@ryanthegentry

Description

@ryanthegentry

Background

I am testing direct channel Taproot Assets LN payments in Polar. I have three litd v0.14.0-alpha.rc1 nodes (each backed by their own bitcoind v27.0 node) Alice, Bob, and Carol. Alice has minted 21M units of a Taproot Asset called USDTest with a decimal_display of 6, and opened a 1M asset channel to Bob (so Alice has 1M assets outbound liquidity). They are both using the improved edge node config --taproot-assets.experimental.rfq.mockoracleassetsperbtc=100000000 (where 1 asset = 1 sat). I am testing expected error messages when Bob generates a sats invoice, and Alice tries to pay it with Taproot Assets.

Your environment

Alice's litd config:

litd
  --httpslisten=0.0.0.0:8443
  --uipassword={{litdPass}}
  --network=regtest
  --lnd-mode=integrated
  --pool-mode=disable
  --loop-mode=disable
  --autopilot.disable
  --lnd.noseedbackup
  --lnd.debuglevel=debug
  --lnd.alias={{name}}
  --lnd.externalip={{name}}
  --lnd.tlsextradomain={{name}}
  --lnd.tlsextradomain={{containerName}}
  --lnd.tlsextradomain=host.docker.internal
  --lnd.listen=0.0.0.0:9735
  --lnd.rpclisten=0.0.0.0:10009
  --lnd.restlisten=0.0.0.0:8080
  --lnd.bitcoin.active
  --lnd.bitcoin.regtest
  --lnd.bitcoin.node=bitcoind
  --lnd.bitcoind.rpchost={{backendName}}
  --lnd.bitcoind.rpcuser={{rpcUser}}
  --lnd.bitcoind.rpcpass={{rpcPass}}
  --lnd.bitcoind.zmqpubrawblock=tcp://{{backendName}}:28334
  --lnd.bitcoind.zmqpubrawtx=tcp://{{backendName}}:28335
  --taproot-assets.allow-public-uni-proof-courier
  --taproot-assets.universe.public-access=rw
  --taproot-assets.universe.sync-all-assets
  --taproot-assets.allow-public-stats
  --taproot-assets.universerpccourier.skipinitdelay
  --taproot-assets.universerpccourier.backoffresetwait=1s
  --taproot-assets.universerpccourier.numtries=5
  --taproot-assets.universerpccourier.initialbackoff=300ms
  --taproot-assets.universerpccourier.maxbackoff=600ms
  --taproot-assets.experimental.rfq.priceoracleaddress=use_mock_price_oracle_service_promise_to_not_use_on_mainnet
  --taproot-assets.experimental.rfq.mockoracleassetsperbtc=100000000
  --lnd.trickledelay=50
  --lnd.gossip.sub-batch-delay=5ms
  --lnd.caches.rpc-graph-cache-duration=100ms
  --lnd.default-remote-max-htlcs=483
  --lnd.dust-threshold=5000000
  --lnd.protocol.option-scid-alias
  --lnd.protocol.zero-conf
  --lnd.protocol.simple-taproot-chans
  --lnd.protocol.simple-taproot-overlay-chans
  --lnd.protocol.wumbo-channels 
  --lnd.accept-keysend
  --lnd.protocol.custom-message=17
  --taproot-assets.proofcourieraddr=universerpc://0.0.0.0:13003

Alice's tapcli getinfo output:

litd@alice:/$ tapcli getinfo
{
    "version": "0.5.0-alpha.rc1 commit=v0.5.0-rc1",
    "lnd_version": "0.18.4-beta.rc1",
    "network": "regtest",
    "lnd_identity_pubkey": "031bed3db7e2f0a440e6a715ae95ff447c13e2b40349b2133890e42b80fa774eec",
    "node_alias": "alice",
    "block_height": 134,
    "block_hash": "7908ed37fcbbe954fadac8f9eaea1546138ddaad292646a9afb9d2285713eeb8",
    "sync_to_chain": true
}

Bob's litd config:

litd
  --httpslisten=0.0.0.0:8443
  --uipassword={{litdPass}}
  --network=regtest
  --lnd-mode=integrated
  --pool-mode=disable
  --loop-mode=disable
  --autopilot.disable
  --lnd.noseedbackup
  --lnd.debuglevel=debug
  --lnd.alias={{name}}
  --lnd.externalip={{name}}
  --lnd.tlsextradomain={{name}}
  --lnd.tlsextradomain={{containerName}}
  --lnd.tlsextradomain=host.docker.internal
  --lnd.listen=0.0.0.0:9735
  --lnd.rpclisten=0.0.0.0:10009
  --lnd.restlisten=0.0.0.0:8080
  --lnd.bitcoin.active
  --lnd.bitcoin.regtest
  --lnd.bitcoin.node=bitcoind
  --lnd.bitcoind.rpchost={{backendName}}
  --lnd.bitcoind.rpcuser={{rpcUser}}
  --lnd.bitcoind.rpcpass={{rpcPass}}
  --lnd.bitcoind.zmqpubrawblock=tcp://{{backendName}}:28334
  --lnd.bitcoind.zmqpubrawtx=tcp://{{backendName}}:28335
  --taproot-assets.allow-public-uni-proof-courier
  --taproot-assets.universe.public-access=rw
  --taproot-assets.universe.sync-all-assets
  --taproot-assets.allow-public-stats
  --taproot-assets.universerpccourier.skipinitdelay
  --taproot-assets.universerpccourier.backoffresetwait=1s
  --taproot-assets.universerpccourier.numtries=5
  --taproot-assets.universerpccourier.initialbackoff=300ms
  --taproot-assets.universerpccourier.maxbackoff=600ms
  --taproot-assets.experimental.rfq.priceoracleaddress=use_mock_price_oracle_service_promise_to_not_use_on_mainnet
  --taproot-assets.experimental.rfq.mockoracleassetsperbtc=100000000
  --lnd.trickledelay=50
  --lnd.gossip.sub-batch-delay=5ms
  --lnd.caches.rpc-graph-cache-duration=100ms
  --lnd.default-remote-max-htlcs=483
  --lnd.dust-threshold=5000000
  --lnd.protocol.option-scid-alias
  --lnd.protocol.zero-conf
  --lnd.protocol.simple-taproot-chans
  --lnd.protocol.simple-taproot-overlay-chans
  --lnd.protocol.wumbo-channels 
  --lnd.accept-keysend
  --lnd.protocol.custom-message=17
  --taproot-assets.proofcourieraddr=universerpc://0.0.0.0:13003

Bob's tapcli getinfo output:

litd@bob:/$ tapcli getinfo
{
    "version": "0.5.0-alpha.rc1 commit=v0.5.0-rc1",
    "lnd_version": "0.18.4-beta.rc1",
    "network": "regtest",
    "lnd_identity_pubkey": "033e9085cfdbd1e33fc64acad580d74a12982d2abfe114d5294387c60a34709819",
    "node_alias": "bob",
    "block_height": 134,
    "block_hash": "7908ed37fcbbe954fadac8f9eaea1546138ddaad292646a9afb9d2285713eeb8",
    "sync_to_chain": true
}

Steps to reproduce

  1. Check the beginning channel balances:
litd@alice:/$ lncli listchannels
{
    "channels": [
        {
            "active": true,
            "remote_pubkey": "033e9085cfdbd1e33fc64acad580d74a12982d2abfe114d5294387c60a34709819",
            "channel_point": "5e60489204027e197f27197ba5e11773db5562683ec6e0228a73daa553b67b28:0",
            "chan_id": "144036023304192",
            "capacity": "100000",
            "local_balance": "96920",
            "remote_balance": "0",
            "commit_fee": "2750",
            "commit_weight": "614",
            "fee_per_kw": "2500",
            "unsettled_balance": "0",
            "total_satoshis_sent": "0",
            "total_satoshis_received": "0",
            "num_updates": "0",
            "pending_htlcs": [],
            "csv_delay": 144,
            "private": true,
            "initiator": true,
            "chan_status_flags": "ChanStatusDefault",
            "local_chan_reserve_sat": "1000",
            "remote_chan_reserve_sat": "1062",
            "static_remote_key": false,
            "commitment_type": "SIMPLE_TAPROOT_OVERLAY",
            "lifetime": "75",
            "uptime": "75",
            "close_address": "",
            "push_amount_sat": "0",
            "thaw_height": 0,
            "local_constraints": {
                "csv_delay": 144,
                "chan_reserve_sat": "1000",
                "dust_limit_sat": "354",
                "max_pending_amt_msat": "99000000",
                "min_htlc_msat": "1",
                "max_accepted_htlcs": 83
            },
            "remote_constraints": {
                "csv_delay": 144,
                "chan_reserve_sat": "1062",
                "dust_limit_sat": "354",
                "max_pending_amt_msat": "99000000",
                "min_htlc_msat": "1",
                "max_accepted_htlcs": 83
            },
            "alias_scids": [
                "17592186044416000000"
            ],
            "zero_conf": false,
            "zero_conf_confirmed_scid": "0",
            "peer_alias": "bob",
            "peer_scid_alias": "17592186044416000001",
            "memo": "",
            "custom_channel_data": {
                "assets": [
                    {
                        "asset_utxo": {
                            "version": 1,
                            "asset_genesis": {
                                "genesis_point": "3492f857a3ce5d2ec2c1fc4d1c5e6916a3318e3f93d65597025714e4eca0abbb:0",
                                "name": "USDTest",
                                "meta_hash": "98c6ac28bc381a4bb270d94896129f355950eb8248a59c54ea933b68d1c7d202",
                                "asset_id": "e663f95284a366d7c05a989a7a85f5ef0ed7943fc21bd03515095646ea438203"
                            },
                            "amount": 1000000,
                            "script_key": "0250aaeb166f4234650d84a2d8a130987aeaf6950206e0905401ee74ff3f8d18e6"
                        },
                        "capacity": 1000000,
                        "local_balance": 1000000,
                        "remote_balance": 0
                    }
                ]
            }
        }
    ]
}
  1. Bob generates a sats invoice:
litd@bob:/$ lncli addinvoice 1
{
    "r_hash": "671849c9eecce2d8671585df368c3496d06c4007748d424519edf3f66a0d70e1",
    "payment_request": "lnbcrt10n1pn4ptkupp5vuvynj0wen3dsec4sh0ndrp5jmgxcsq8wjx5y3geahelv6sdwrssdqqcqzzsxqyz5vqsp5rqrsv8u0xrxjyjge5av674y4mg8p0787ssus2xvxv40jjhta9u9q9qxpqysgq8lk8uhhd59xqd0qglv6s0yxjf3fk3vf0eyjrqnmmzqvs4flmmn6hfu7kgkh2vcglm7gjlh506ktywwx9nwhqqfsx8kl2lwpw04t4e2qpekk56s",
    "add_index": "1",
    "payment_addr": "1807061f8f30cd224919a759af5495da0e17f8fe8439051986655f295d7d2f0a"
}
  1. Alice attempts to pay it with Taproot Assets, instead of sats:
litd@alice:/$ litcli ln payinvoice --pay_req lnbcrt10n1pn4ptkupp5vuvynj0wen3dsec4sh0ndrp5jmgxcsq8wjx5y3geahelv6sdwrssdqqcqzzsxqyz5vqsp5rqrsv8u0xrxjyjge5av674y4mg8p0787ssus2xvxv40jjhta9u9q9qxpqysgq8lk8uhhd59xqd0qglv6s0yxjf3fk3vf0eyjrqnmmzqvs4flmmn6hfu7kgkh2vcglm7gjlh506ktywwx9nwhqqfsx8kl2lwpw04t4e2qpekk56s --asset_id e663f95284a366d7c05a989a7a85f5ef0ed7943fc21bd03515095646ea438203 --rfq_peer_pubkey 033e9085cfdbd1e33fc64acad580d74a12982d2abfe114d5294387c60a34709819
Payment hash: 671849c9eecce2d8671585df368c3496d06c4007748d424519edf3f66a0d70e1
Description: 
Amount (in satoshis): 1
Fee limit (in satoshis): 1
Destination: 033e9085cfdbd1e33fc64acad580d74a12982d2abfe114d5294387c60a34709819
Confirm payment (yes/no): yes
Got quote for 1 asset units at 1000 msat/unit from peer 033e9085cfdbd1e33fc64acad580d74a12982d2abfe114d5294387c60a34709819 with SCID 17823997510213151581
+------------+--------------+--------------+--------------+-----+----------+-----------------+-------+
| HTLC_STATE | ATTEMPT_TIME | RESOLVE_TIME | RECEIVER_AMT | FEE | TIMELOCK | CHAN_OUT        | ROUTE |
+------------+--------------+--------------+--------------+-----+----------+-----------------+-------+
| SUCCEEDED  |        0.379 |        1.195 | 1            | 0   |      217 | 144036023304192 | bob   |
+------------+--------------+--------------+--------------+-----+----------+-----------------+-------+
Amount + fee:   1 + 0 sat
Payment hash:   671849c9eecce2d8671585df368c3496d06c4007748d424519edf3f66a0d70e1
Payment status: SUCCEEDED, preimage: 5c4883f1efd347055a4269750a37ece9fe9e610e5c0a2b2d8d4a0e5ae14ea0f5
  1. Check final channel balances:
litd@alice:/$ lncli listchannels
{
    "channels": [
        {
            "active": true,
            "remote_pubkey": "033e9085cfdbd1e33fc64acad580d74a12982d2abfe114d5294387c60a34709819",
            "channel_point": "5e60489204027e197f27197ba5e11773db5562683ec6e0228a73daa553b67b28:0",
            "chan_id": "144036023304192",
            "capacity": "100000",
            "local_balance": "96566",
            "remote_balance": "354",
            "commit_fee": "2420",
            "commit_weight": "958",
            "fee_per_kw": "2500",
            "unsettled_balance": "0",
            "total_satoshis_sent": "354",
            "total_satoshis_received": "0",
            "num_updates": "2",
            "pending_htlcs": [],
            "csv_delay": 144,
            "private": true,
            "initiator": true,
            "chan_status_flags": "ChanStatusDefault",
            "local_chan_reserve_sat": "1000",
            "remote_chan_reserve_sat": "1062",
            "static_remote_key": false,
            "commitment_type": "SIMPLE_TAPROOT_OVERLAY",
            "lifetime": "900",
            "uptime": "900",
            "close_address": "",
            "push_amount_sat": "0",
            "thaw_height": 0,
            "local_constraints": {
                "csv_delay": 144,
                "chan_reserve_sat": "1000",
                "dust_limit_sat": "354",
                "max_pending_amt_msat": "99000000",
                "min_htlc_msat": "1",
                "max_accepted_htlcs": 83
            },
            "remote_constraints": {
                "csv_delay": 144,
                "chan_reserve_sat": "1062",
                "dust_limit_sat": "354",
                "max_pending_amt_msat": "99000000",
                "min_htlc_msat": "1",
                "max_accepted_htlcs": 83
            },
            "alias_scids": [
                "17592186044416000000"
            ],
            "zero_conf": false,
            "zero_conf_confirmed_scid": "0",
            "peer_alias": "bob",
            "peer_scid_alias": "17592186044416000001",
            "memo": "",
            "custom_channel_data": {
                "assets": [
                    {
                        "asset_utxo": {
                            "version": 1,
                            "asset_genesis": {
                                "genesis_point": "3492f857a3ce5d2ec2c1fc4d1c5e6916a3318e3f93d65597025714e4eca0abbb:0",
                                "name": "USDTest",
                                "meta_hash": "98c6ac28bc381a4bb270d94896129f355950eb8248a59c54ea933b68d1c7d202",
                                "asset_id": "e663f95284a366d7c05a989a7a85f5ef0ed7943fc21bd03515095646ea438203"
                            },
                            "amount": 1000000,
                            "script_key": "0250aaeb166f4234650d84a2d8a130987aeaf6950206e0905401ee74ff3f8d18e6"
                        },
                        "capacity": 1000000,
                        "local_balance": 999999,
                        "remote_balance": 1
                    }
                ]
            }
        }
    ]
}

Expected behavior

The payment should fail with a FAILURE_REASON_INCORRECT_PAYMENT_DETAILS error. This is what happens in the reverse scenario if Bob invoices Taproot Assets, and Alice attempts to pay with sats. Will include those details in a follow-up comment.

Actual behavior

Bob invoiced 1 sat. Alice paid him 1 Taproot Asset + the 354 sat dust amount.

Logs for Alice and Bob
alice-direct.log
bob-direct.log
attached.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Status

✅ Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions