Hi all,
This quarter I am working at improving lnd's in-house accounting, so that it is
easier for individuals and businesses to see exactly how funds are moving around
their nodes. I would like to build something that is as useful as possible,
specifically for businesses building on lnd (because the overhead of auditing
a node yourself is quite high), so I want to reach out to this list for early
feedback on the design.
The components of the project are described in detail in the sections
that follow. For each section, I am looking for feedback as to whether this
will format would be useful to you/your business and comments on any changes
or additions that you believe would be beneficial. If you don't want to
publicly reply on this list, please do reach out to me at ca...@lightning.engineering.
1. Per Channel Accounting
Goal: Obtain an audit trail which explains exactly how your funds moved within
a channel
Deliverable: A per channel statement which allows you to step through balance
changes from open -> close balances.
Channels can be closed in a variety of ways (cooperative, force, breach
and justice), so I am going to split this section by channel close type, with a
scenario and example output for each. The case where your node loses state and
accidentally breaches will not be covered, because there is little we can do
without an in-state database.
1.1 Cooperative Close:
Provide information about the opening and closing transactions, who initiated
them and whether we paid fees, as well as a channel usage statement which details
every htlc which was settled over this channel (including forwards). Since this
case covers cooperative closes, there are no on-chain htlcs.
Scenario:
We open a 50000 sat channel, paying 8950 sat on chain fees
We send 100 sat over the channel
We receive 20 sat over the channel
We forward a 1000 sat htlc out over the channel
We accept a 500 sat incoming htlc on the channel
The remote party closes the channel cooperatively, we pay 9000 sat fees because we opened the channel
Example Output:
Opening TxID: e638087f7b184157468455afb2816a7b059bb7b604b30fd12e2a40e3639ea8fa
Channel Initiator: local
Fees Paid: 8950 sat
Opening Balance: 50000 sat
Off Chain Statement:
Type: Send
Amount: 100 sat
Hash: 2009df85f81c6213e1525bf302a44d458ccd194ff16eff81677cccb459cae09a
Type: Receive
Amount: 20 sat
Hash: 7b7dbde1e2e265e7cd5c17bddd96f3e0b0e9bdc2e40ecec66c81bb367642cb2b
Type: Outgoing HTLC Forward
Amount: 1000 sat
Hash: 18574b471dad3a34efaf6b56f2f2977cbba0db084ef96dc7a163fe5630dffbf7
Type: Incoming HTLC Forward
Amount: 490 sat
Hash: 77b193ac3c63ac06c9803b13b63b62989425a1ff3a74ac1ca7eb4015e1b9e688
Fees: 10 sat
Closing TxID: 5da9507a6371625a3902c076fc013dc3a51d0f20046c9712cf3348ea5d687eb9
Close Initiator: remote
Fees Paid: 9000 sat
Close Type: Cooperative
Close Balance:
Amount: 40420 sat
Time Locked: false
1.2 Force Close:
Force closes go to chain with active htlcs, so an extra on chain statement
section is added to provide a list of the htlcs that we had to resolve on chain.
This on chain statement will include information about how the htlcs were resolved:
Unresolved: no action has been taken for this htlc at time of statement generation, we provide the height at which the htlc times out on chain
Local success swept: we claimed an incoming htlc with the preimage (receive/ incoming fwd)
Remote timeout swept: remote reclaimed our incoming htlc after timeout (receive/ incoming fwd)
Local timeout swept: we reclaimed our outgoing htlc after timeout (send/ outgoing fwd)
Remote success swept: remote claimed our outgoing htlc with preimage (send/ outgoing fwd)
Scenario:
The remote party opens a channel to us, we pay no on chain fees
We receive 10000 sat over the channel
We send 100 sat over the channel
We commit to htlcs for a 20 sat send, 10 sat receive, 200 sat outgoing forward and 500 sat incoming forward but do not fulfill them
Our peer goes offline, and we get frustrated and force close the channel, paying no fees
The peer comes back online, and sweeps the success output for our send
The outgoing forward times out, so we sweep the timeout output back to our wallet
The incoming forward has not timed out at the time of statement generation
Example Output:
Opening TxId: e638087f7b184157468455afb2816a7b059bb7b604b30fd12e2a40e3639ea8fa
Channel Initiator: remote
Fees Paid: 0 sat
Opening Balance: 0 sat
Off Chain Statement:
Type: Receive
Amount: 10000 sat
Hash: 1bf08ff13554432e1184c24cffcef4b5017afe68cabe790f13700ad5126f3053
Type: Send
Amount 100 sat
Hash: 2009df85f81c6213e1525bf302a44d458ccd194ff16eff81677cccb459cae09a
On Chain Statement:
Type: Send
Amount: 20 sat
Hash: 7b7dbde1e2e265e7cd5c17bddd96f3e0b0e9bdc2e40ecec66c81bb367642cb2b
Resolution:
Type: Remote Success Sweep
TxID: 6c5c989130a378c89dab343e6e2bbc6a358c652a5671384d91226a8fa45824cf
Type: Receive
Amount: 10 sat
Hash: 222adebe7444df51b1a58322906ca8dcd57e875fbf315487e1f2ef66a705dc7b
Resolution:
Type: Local Success Sweep
TxID: 6c5c989130a378c89dab343e6e2bbc6a358c652a5671384d91226a8fa45824cf
Fee: 5 sat
Type: Outgoing HTLC Forward
Amount: 200 sat
Hash: 18574b471dad3a34efaf6b56f2f2977cbba0db084ef96dc7a163fe5630dffbf7
Resolution:
Type: Local Timeout Sweep
TxID: 6c5c989130a378c89dab343e6e2bbc6a358c652a5671384d91226a8fa45824cf
Fee: 5 sat
Type: Incoming HTLC Forward
Amount: 500 sat
Hash: 77b193ac3c63ac06c9803b13b63b62989425a1ff3a74ac1ca7eb4015e1b9e688
Resolution:
Type: Unresolved
Timeout Height: 613402
Closing TxID: 5f438e4ea81e3ee1f933f0c0c5632b18134b6df69b6592151b6bfe7948b356bc
Close Initiator: local
Fees Paid: 0 sat
Close Type: Force
Close Balance:
Amount: 9890
Time locked: true
1.3 Breach Close:
In the case of a breach close, we will report on all channel activity until
the point of breach, and provide a breach delta which indicates the amount
lost/gained as a result of the unpunished breach. For the sake of explaining
the position of the breach, commitment states are denoted as C1...Cn in the
scenario run through. For simplicity the breach transaction has no unresolved
htlcs in it. In the case where there are unresolved htlcs, we would include
them as listed above for force closes.
Scenario:
We open a 50000 sat channel, paying 8950 sat on chain fees
We send 1000 sat over the channel (C1)
We receive 20 sat over the channel (C2)
We settle all open htlcs on the channel (C3)
We receive 500 sat over the channel (C4)
The remote party breaches us, by broadcasting C3
We are offline, so we fail to broadcast the justice transaction
Example Output:
Opening TxID: e638087f7b184157468455afb2816a7b059bb7b604b30fd12e2a40e3639ea8fa
Channel Initiator: local
Fees Paid: 8950 sat
Opening Balance: 50000 sat
Off Chain Statement:
Type: Send
Amount: 1000 sat
Hash: 2009df85f81c6213e152548ofa44d458ccd194ff16eff81677cccb459cae09a
Type: Receive
Amount: 20 sat
Hash: 7b7dbde1e2e265e7cd5c17bddd96f3e0b0e9bdc2e40ecec66c81bb367642cb2b
Closing TxID: 5da9507a6371625a3902c076fc013dc3a51d0f20046c9712cf3348ea5d687eb9
Close Initiator: remote
Fees Paid: 9000 sat
Close Type: Breach
Close Balance:
Amount: 49020
Time locked: false
Breach Delta: -500 sat
1.4 Justice Close:
As above, commitments are denoted C1...Cn to make the point of breach clear.
A Justice Delta provides the increase in funds that we earn from punishing
the breach. Note that in the case where the remote party opens the channel
and then breaches, the close fees will be paid out of their available balance,
which will decrease the justice delta by the fee amount.
Scenario:
The remote party opens a 50000 sat channel to us, we pay no on chain fees
We receive 1000 sat over the channel (C1)
We settle all open htlcs on the channel (C2)
We receive 500 sat over the channel (C3)
The remote party breaches us, by broadcasting C2 which has 6750 sats fees
We see the breach, and broadcast a justice transaction
Example Output:
Opening TxId: e638087f7b184157468455afb2816a7b059bb7b604b30fd12e2a40e3639ea8fa
Channel Initiator: remote
Fees Paid: 0 sat
Opening Balance: 0 sat
Off Chain Statement:
Type: Receive
Amount: 1000 sat
Hash: 7b7dbde1e2e265e7cd5c17bddd96f3e0b0e9bdc2e40ecec66c81bb367642cb2b
Closing TxID: 5da9507a6371625a3902c076fc013dc3a51d0f20046c9712cf3348ea5d687eb9
Close Initiator: remote
Fees Paid: 0 sat
Close Type: Breach
Close Balance:
Amount: 1000
Time Locked: false
Justice TxID: 642810e0c37411bfed7c74e284a2819d8154f7efaf738dc65b2e687916222a92
Justice Delta: 42250
2. On-Chain 'utilities'
Goal: Provide a more transparent account of all on chain transactions that lnd
initiates
Deliverable: A list of on chain transactions connected to their lnd purpose
(channel open/close, sweep, user tx)
On chain transactions can have one of the following types, paired with type
relevant metadata:
OpenChannel: the channel ID associated with this channel
CloseChannel the channel ID associated with this channel
HtlcSweep: a list of the htlcs which were swept by this transaction, the channels they were in and the send/receive/forward they correspond to
UserSend: a user set memo that will be specified on send
Example Output:
Type: OpenChannel
TxID: e638087f7b184157468455afb2816a7b059bb7b604b30fd12e2a40e3639ea8fa
Metadata: ChannelID = 1189671581450240
Type: CloseChannel
TxID: 662d705b186b5a0faed737748d27db3126dde2b60a0e64e2c1040d1c7f75098b
Metadata: ChannelID = 1189671581450240
Type: HTLCSweep
TxID:d23ce789e1b8d3d20686a171aea0f64aeb0067768c73aa343d7f9c251ffcaa37
Metadata:
Hash: MQzfSwAvtD+YDGbsEhL0sBKGcp1TnbkTdQxNhZMxhY8
Channel: e638087f7b184157468455afb2816a7b059bb7b604b30fd12e2a40e3639ea8fa
Type: Send
Resolution: Local timeout sweep
Hash: Bmdlg5AM+0AlDWPW4Pb2cLnhQ9w9Q2G3RSUoc41Ch6U
Channel: e638087f7b184157468455afb2816a7b059bb7b604b30fd12e2a40e3639ea8fa
Type: Receive
Resolution: Local success sweep
Hash: 9v/RMsGkW4LIyp0qF/2Z12LOIxybFLjFi1+RIlYJvEU
Channel: 4874925eeeb5aa3ab03a1186da430c26e35f5151e6dccd1b5e6261c082b575de
Type: Outgoing Forward
Resolution: Local timeout sweep
Type: UserSend
TxID: 14387d1ef6fb5f9e56ecb2ad639f949dc321c357785e81e15e9eb1a835eb42ca
Metadata: "user supplied memo, set in the sendcoins api"
Thanks for reading!
- Carla