Lnd: 1 Satoshi Missing After Every Payment

Created on 9 Dec 2017  Â·  10Comments  Â·  Source: lightningnetwork/lnd

This is done using three nodes (alice, bob, charlie) on a local simnet and should be reproducible. I am not sure if this a bug, or is intentional but not accurately presented to the user.

We start with three nodes: alice, bob and charlie. Alice opens a channel with bob, and bob opens a channel with charlie:

$ lncli-alice openchannel 03ab7d85f11f2429b94ce29c7b09b1ae38bb8fa05995b06d42d193e6d08f7f79a5 18688
{
        "funding_txid": "67ed36000b8609d58a4bc976f8905dd877d5b6aa127c53d90b00cbb109cb7c64"
}
$ lncli-bob openchannel 02785eca55d76465aa6f18dc6d7fd6dba2fc7aa47e232543aa17019c77bf909d58 18688
{
        "funding_txid": "193f040ed4fbf32ae98a3de2705b0d951524b1fb89c364b6e80f043beb7e19bb"
}



md5-eab4086fd4c79c2853c3dd0e4510f0e2



$ btcctl generate 4



md5-9f95f6cf09287ba9b8c678aec7577951



$ lncli-bob listchannels
{
    "channels": [
        {
            "active": true,
            "remote_pubkey": "0237b82dfb5bab416142108b011cbd354550a9c7e16aa674cc3d213f0e5b4b2d1b",
            "channel_point": "67ed36000b8609d58a4bc976f8905dd877d5b6aa127c53d90b00cbb109cb7c64:0",
            "chan_id": "1905453651001344",
            "capacity": "18688",
            "local_balance": "0",
            "remote_balance": "10000",
            "commit_fee": "8688",
            "commit_weight": "552",
            "fee_per_kw": "12000",
            "unsettled_balance": "0",
            "total_satoshis_sent": "0",
            "total_satoshis_received": "0",
            "num_updates": "0",
            "pending_htlcs": [
            ],
            "csv_delay": 4
        },
        {
            "active": true,
            "remote_pubkey": "02785eca55d76465aa6f18dc6d7fd6dba2fc7aa47e232543aa17019c77bf909d58",
            "channel_point": "193f040ed4fbf32ae98a3de2705b0d951524b1fb89c364b6e80f043beb7e19bb:0",
            "chan_id": "1905453651066880",
            "capacity": "18688",
            "local_balance": "10000",
            "remote_balance": "0",
            "commit_fee": "8688",
            "commit_weight": "600",
            "fee_per_kw": "12000",
            "unsettled_balance": "0",
            "total_satoshis_sent": "0",
            "total_satoshis_received": "0",
            "num_updates": "0",
            "pending_htlcs": [
            ],
            "csv_delay": 4
        }
    ]
}



md5-ecd6799f9092090de95e295df9b57b26



$ lncli-charlie addinvoice 1000
{
        "r_hash": "4061dffc0ceec9088fc9367523500a40bd61c2029d68e24a440c4fc37e94f782",
        "pay_req": "lnsb10u1pdzk0lxpp5gpsallqvamys3r7fxe6jx5q2gz7krsszn45wyjjyp38uxl5577pqdqqcqzyswlzxmnh8up0krllnhncm0348692jcw4ynk9uuynd8tcxcx58rpn9xwqkz9ct8qmrpazhuc98ppyrsl24xvndffgfjheqn7z6v2gtnjgp9j4wyk"
}



md5-53a8c3d303563d36062c96f9da183a05



$ lncli-alice payinvoice lnsb10u1pdzk0lxpp5gpsallqvamys3r7fxe6jx5q2gz7krsszn45wyjjyp38uxl5577pqdqqcqzyswlzxmnh8up0krllnhncm0348692jcw4ynk9uuynd8tcxcx58rpn9xwqkz9ct8qmrpazhuc98ppyrsl24xvndffgfjheqn7z6v2gtnjgp9j4wyk
{
        "payment_error": "",
        "payment_preimage": "58c270f16d8d331f82a86cb66d07e54f7ad28c0e63e946d65342301f48ddfaed",
        "payment_route": {
                "total_time_lock": 2024,
                "total_fees": 1,
                "total_amt": 1001,
                "hops": [
                        {
                                "chan_id": 1905453651001344,
                                "chan_capacity": 18688,
                                "amt_to_forward": 1000,
                                "fee": 1,
                                "expiry": 1880
                        },
                        {
                                "chan_id": 1905453651066880,
                                "chan_capacity": 18688,
                                "amt_to_forward": 1000,
                                "expiry": 1880
                        }
                ]
        }
}



md5-b7b2e8fb4a7a773f2f7767e621948aef



$ lncli-bob listchannels
{
    "channels": [
        {
            "active": true,
            "remote_pubkey": "0237b82dfb5bab416142108b011cbd354550a9c7e16aa674cc3d213f0e5b4b2d1b",
            "channel_point": "67ed36000b8609d58a4bc976f8905dd877d5b6aa127c53d90b00cbb109cb7c64:0",
            "chan_id": "1905453651001344",
            "capacity": "18688",
            "local_balance": "1001",
            "remote_balance": "8998",
            "commit_fee": "8688",
            "commit_weight": "724",
            "fee_per_kw": "12000",
            "unsettled_balance": "0",
            "total_satoshis_sent": "0",
            "total_satoshis_received": "1001",
            "num_updates": "2",
            "pending_htlcs": [
            ],
            "csv_delay": 4
        },
        {
            "active": true,
            "remote_pubkey": "02785eca55d76465aa6f18dc6d7fd6dba2fc7aa47e232543aa17019c77bf909d58",
            "channel_point": "193f040ed4fbf32ae98a3de2705b0d951524b1fb89c364b6e80f043beb7e19bb:0",
            "chan_id": "1905453651066880",
            "capacity": "18688",
            "local_balance": "9000",
            "remote_balance": "1000",
            "commit_fee": "8688",
            "commit_weight": "724",
            "fee_per_kw": "12000",
            "unsettled_balance": "0",
            "total_satoshis_sent": "1000",
            "total_satoshis_received": "0",
            "num_updates": "2",
            "pending_htlcs": [
            ],
            "csv_delay": 4
        }
    ]
}

Channel 2 (between bob and charlie) has 9000 satoshis on bob's side and 1000 satoshis on charlie's side. The total sum is 10000 satoshis.

Channel 1 (between alice and bob) has 8998 satoshis on alice's side and 1001 satoshis on bob's side. 1001 comprising of the 1000 satoshi payment to charlie plus the 1 satoshi fee as shown in the payment output previously.

The total sum is 9999 satoshis. There is one satoshi missing from this channel that is completely unaccounted for. In alice's payment output, it shows the total amount sent as 1001 satoshis. Hence a user would expect the new balance on alice's side of channel 1 to be 10000-1001 = 8999 satoshis. However, we are seeing one less, 8998 satoshis. It seems as if this satoshi has disappeared.

Most helpful comment

One last comment: the fee paid _within_ the protocol isn't 1 SAT, it's actually 1001 mSAT. So Alice ends up with 8998999 mSAT (8998.999 SAT). Bob similarly ends up with 1001001 mSAT (1001.001 SAT). 8998.999 + 1001.001 = 10000.0 SAT. However, we can't express that fractional amount (totaling 1 SAT across both commitment transactions) so it goes to miner fees.

A commit will be pushed shortly to detect this and show the proper commitment fee. Thanks for the initial report! I can understand how this may have freaked out users, as without knowledge of the underlying protocol it looks like 1 satoshi is missing. 🙇

Post-fix:

â›° lncli listchannels
{
    "channels": [
        {
            "active": true,
            "remote_pubkey": "03a459d48a84a6909402824da2a80f95d9fc80c8dd06dcfb1c0cfbf28f8101d0c4",
            "channel_point": "4f8d04670b3096c650e4ccd8ce54b3072e7e1fd3c3a897967291e8cf74b315ee:0",
            "chan_id": "1695446930096128",
            "capacity": "18688",
            "local_balance": "7997",
            "remote_balance": "2002",
            "commit_fee": "8689",
            "commit_weight": "724",
            "fee_per_kw": "12000",
            "unsettled_balance": "0",
            "total_satoshis_sent": "2002",
            "total_satoshis_received": "0",
            "num_updates": "4",
            "pending_htlcs": [
            ]
        }
    ]
}

All 10 comments

Even closing this channel and examining the closing transaction shows one satoshi missing:

$ lncli-bob closechannel 67ed36000b8609d58a4bc976f8905dd877d5b6aa127c53d90b00cbb109cb7c64
{
        "closing_txid": "eeb75f0b6caf3e67714cc44c3325160fc3e712f7a87be14091938e461a2088b1"
}

$ btcctl decoderawtransaction `btcctl getrawtransaction eeb75f0b6caf3e67714cc44c3325160fc3e712f7a87be14091938e461a2088b1`
{
  "txid": "eeb75f0b6caf3e67714cc44c3325160fc3e712f7a87be14091938e461a2088b1",
  "version": 2,
  "locktime": 0,
  "vin": [
    {
      "txid": "67ed36000b8609d58a4bc976f8905dd877d5b6aa127c53d90b00cbb109cb7c64",
      "vout": 0,
      "scriptSig": {
        "asm": "",
        "hex": ""
      },
      "txinwitness": [
        "",
        "3045022100e1b628393d85d2137e0c452e699b50dc109f4edee13bdebb96486efe80fb79bd02201c0c8b0a53b14fd6127677e4e1a355a67d80aea5289d5a5a462da6807f3a783101",
        "3045022100c48ca69ce3824d95da45eb63c12fc69fccb845d4f4d0530b4b48116ec60b47900220363e4e5486c947c75a0e70e401ff6ef466ac342179b77abff038e073c326edf701",
        "5221023f27e8373703af11f73cc90def123c5db5d49981d7f7b0317c54c6be68b18938210394862ce2fb51a556fa5ea8f09e643d0ca072d3cbd7287d8fe817c1eaea172f2352ae"
      ],
      "sequence": 2155206757
    }
  ],
  "vout": [
    {
      "value": 0.00001001,
      "n": 0,
      "scriptPubKey": {
        "asm": "0 5bdd389e23aecb69b1b263971abdcdef0c0ad732",
        "hex": "00145bdd389e23aecb69b1b263971abdcdef0c0ad732",
        "reqSigs": 1,
        "type": "witness_v0_keyhash",
        "addresses": [
          "sb1qt0wn383r4m9knvdjvwt340wdauxq44ejwy5v6n"
        ]
      }
    },
    {
      "value": 0.00008998,
      "n": 1,
      "scriptPubKey": {
        "asm": "0 d8c46d6d2f3ee49ddaf79c34a10d743e960b6084",
        "hex": "0014d8c46d6d2f3ee49ddaf79c34a10d743e960b6084",
        "reqSigs": 1,
        "type": "witness_v0_keyhash",
        "addresses": [
          "sb1qmrzx6mf08mjfmkhhns62zrt586tqkcyy0rzkue"
        ]
      }
    }
  ]
}

At any given point, we may be sending an additional satoshi to miner's fees. This is a result of the internal usage of milli-satoshis and our policy of always rounding down (to go from mSAT -> SAT). In your example Alice ends up with a something like 1900 mSAT, which is rounded down to 1 SAT.

If the mining fee has increased as a result of the updated state, I would expect the commit_fee on the channel to reflect this.

It doesn't as this isn't an "explicit" fee. It's an artefact of the usage of mSAT within the protocol.

Note that further flows which create whole satoshi fee amounts in either direction can cause that 1 SAT to be re-credited.

Sorry, you're internally representing currency at a greater precision that Bitcoin supports, rounding it and not making the discrepancy visible to the user?

This is on the same scale of error as storing currency as a double and then hand waving away the inevitable problems with accurately storing values.

It's not acceptable for a financial protocol to 'round off' and drop currency like this. It's deeply disturbing frankly.

At what point is the missing satoshi cleared to the correct user?

This is on the same scale of error as storing currency as a double and then hand waving away the inevitable problems with accurately storing values.

Not at all, we are using fixed point arithmetic here, no doubles involved. The error is bounded to a single satoshi. That single satoshi may end up adding to the commitment transaction's miner fee. Alternatively, an additional payment flow may end up restoring that satoshi.

If you would like to continue this discussion @philipwhiuk, I recommend you make an issue in the spec's repo: https://github.com/lightningnetwork/lightning-rfc/issues

That single satoshi may end up
an additional payment flows may end up restoring that satoshi

Could we get more certainty?

One last comment: the fee paid _within_ the protocol isn't 1 SAT, it's actually 1001 mSAT. So Alice ends up with 8998999 mSAT (8998.999 SAT). Bob similarly ends up with 1001001 mSAT (1001.001 SAT). 8998.999 + 1001.001 = 10000.0 SAT. However, we can't express that fractional amount (totaling 1 SAT across both commitment transactions) so it goes to miner fees.

A commit will be pushed shortly to detect this and show the proper commitment fee. Thanks for the initial report! I can understand how this may have freaked out users, as without knowledge of the underlying protocol it looks like 1 satoshi is missing. 🙇

Post-fix:

â›° lncli listchannels
{
    "channels": [
        {
            "active": true,
            "remote_pubkey": "03a459d48a84a6909402824da2a80f95d9fc80c8dd06dcfb1c0cfbf28f8101d0c4",
            "channel_point": "4f8d04670b3096c650e4ccd8ce54b3072e7e1fd3c3a897967291e8cf74b315ee:0",
            "chan_id": "1695446930096128",
            "capacity": "18688",
            "local_balance": "7997",
            "remote_balance": "2002",
            "commit_fee": "8689",
            "commit_weight": "724",
            "fee_per_kw": "12000",
            "unsettled_balance": "0",
            "total_satoshis_sent": "2002",
            "total_satoshis_received": "0",
            "num_updates": "4",
            "pending_htlcs": [
            ]
        }
    ]
}

Could we get more certainty?

Continuing from my example above, if Bob sends Alice 1 mSAT, then both parties will now have a whole number of satoshis. This may have been a multi-hop payment, or a direct payment.

Was this page helpful?
0 / 5 - 0 ratings