• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 13211764208

08 Feb 2025 03:08AM UTC coverage: 49.288% (-9.5%) from 58.815%
13211764208

Pull #9489

github

calvinrzachman
itest: verify switchrpc server enforces send then track

We prevent the rpc server from allowing onion dispatches for
attempt IDs which have already been tracked by rpc clients.

This helps protect the client from leaking a duplicate onion
attempt. NOTE: This is not the only method for solving this
issue! The issue could be addressed via careful client side
programming which accounts for the uncertainty and async
nature of dispatching onions to a remote process via RPC.
This would require some lnd ChannelRouter changes for how
we intend to use these RPCs though.
Pull Request #9489: multi: add BuildOnion, SendOnion, and TrackOnion RPCs

474 of 990 new or added lines in 11 files covered. (47.88%)

27321 existing lines in 435 files now uncovered.

101192 of 205306 relevant lines covered (49.29%)

1.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

10.64
/lnwallet/aux_leaf_store.go
1
package lnwallet
2

3
import (
4
        "github.com/btcsuite/btcd/btcutil"
5
        "github.com/btcsuite/btcd/chaincfg/chainhash"
6
        "github.com/btcsuite/btcd/wire"
7
        "github.com/lightningnetwork/lnd/channeldb"
8
        "github.com/lightningnetwork/lnd/fn/v2"
9
        "github.com/lightningnetwork/lnd/input"
10
        "github.com/lightningnetwork/lnd/lntypes"
11
        "github.com/lightningnetwork/lnd/lnwire"
12
        "github.com/lightningnetwork/lnd/tlv"
13
)
14

15
// CommitSortFunc is a function type alias for a function that sorts the
16
// commitment transaction outputs. The second parameter is a list of CLTV
17
// timeouts that must correspond to the number of transaction outputs, with the
18
// value of 0 for non-HTLC outputs. The HTLC indexes are needed to have a
19
// deterministic sort value for HTLCs that have the identical amount, CLTV
20
// timeout and payment hash (e.g. multiple MPP shards of the same payment, where
21
// the on-chain script would be identical).
22
type CommitSortFunc func(tx *wire.MsgTx, cltvs []uint32,
23
        indexes []input.HtlcIndex) error
24

25
// DefaultCommitSort is the default commitment sort function that sorts the
26
// commitment transaction inputs and outputs according to BIP69. The second
27
// parameter is a list of CLTV timeouts that must correspond to the number of
28
// transaction outputs, with the value of 0 for non-HTLC outputs. The third
29
// parameter is unused for the default sort function.
30
func DefaultCommitSort(tx *wire.MsgTx, cltvs []uint32,
31
        _ []input.HtlcIndex) error {
3✔
32

3✔
33
        InPlaceCommitSort(tx, cltvs)
3✔
34
        return nil
3✔
35
}
3✔
36

37
// CommitAuxLeaves stores two potential auxiliary leaves for the remote and
38
// local output that may be used to augment the final tapscript trees of the
39
// commitment transaction.
40
type CommitAuxLeaves struct {
41
        // LocalAuxLeaf is the local party's auxiliary leaf.
42
        LocalAuxLeaf input.AuxTapLeaf
43

44
        // RemoteAuxLeaf is the remote party's auxiliary leaf.
45
        RemoteAuxLeaf input.AuxTapLeaf
46

47
        // OutgoingHTLCLeaves is the set of aux leaves for the outgoing HTLCs
48
        // on this commitment transaction.
49
        OutgoingHtlcLeaves input.HtlcAuxLeaves
50

51
        // IncomingHTLCLeaves is the set of aux leaves for the incoming HTLCs
52
        // on this commitment transaction.
53
        IncomingHtlcLeaves input.HtlcAuxLeaves
54
}
55

56
// AuxChanState is a struct that holds certain fields of the
57
// channeldb.OpenChannel struct that are used by the aux components. The data
58
// is copied over to prevent accidental mutation of the original channel state.
59
type AuxChanState struct {
60
        // ChanType denotes which type of channel this is.
61
        ChanType channeldb.ChannelType
62

63
        // FundingOutpoint is the outpoint of the final funding transaction.
64
        // This value uniquely and globally identifies the channel within the
65
        // target blockchain as specified by the chain hash parameter.
66
        FundingOutpoint wire.OutPoint
67

68
        // ShortChannelID encodes the exact location in the chain in which the
69
        // channel was initially confirmed. This includes: the block height,
70
        // transaction index, and the output within the target transaction.
71
        //
72
        // If IsZeroConf(), then this will the "base" (very first) ALIAS scid
73
        // and the confirmed SCID will be stored in ConfirmedScid.
74
        ShortChannelID lnwire.ShortChannelID
75

76
        // IsInitiator is a bool which indicates if we were the original
77
        // initiator for the channel. This value may affect how higher levels
78
        // negotiate fees, or close the channel.
79
        IsInitiator bool
80

81
        // Capacity is the total capacity of this channel.
82
        Capacity btcutil.Amount
83

84
        // LocalChanCfg is the channel configuration for the local node.
85
        LocalChanCfg channeldb.ChannelConfig
86

87
        // RemoteChanCfg is the channel configuration for the remote node.
88
        RemoteChanCfg channeldb.ChannelConfig
89

90
        // ThawHeight is the height when a frozen channel once again becomes a
91
        // normal channel. If this is zero, then there're no restrictions on
92
        // this channel. If the value is lower than 500,000, then it's
93
        // interpreted as a relative height, or an absolute height otherwise.
94
        ThawHeight uint32
95

96
        // TapscriptRoot is an optional tapscript root used to derive the MuSig2
97
        // funding output.
98
        TapscriptRoot fn.Option[chainhash.Hash]
99

100
        // CustomBlob is an optional blob that can be used to store information
101
        // specific to a custom channel type. This information is only created
102
        // at channel funding time, and after wards is to be considered
103
        // immutable.
104
        CustomBlob fn.Option[tlv.Blob]
105
}
106

107
// NewAuxChanState creates a new AuxChanState from the given channel state.
UNCOV
108
func NewAuxChanState(chanState *channeldb.OpenChannel) AuxChanState {
×
UNCOV
109
        return AuxChanState{
×
UNCOV
110
                ChanType:        chanState.ChanType,
×
UNCOV
111
                FundingOutpoint: chanState.FundingOutpoint,
×
UNCOV
112
                ShortChannelID:  chanState.ShortChannelID,
×
UNCOV
113
                IsInitiator:     chanState.IsInitiator,
×
UNCOV
114
                Capacity:        chanState.Capacity,
×
UNCOV
115
                LocalChanCfg:    chanState.LocalChanCfg,
×
UNCOV
116
                RemoteChanCfg:   chanState.RemoteChanCfg,
×
UNCOV
117
                ThawHeight:      chanState.ThawHeight,
×
UNCOV
118
                TapscriptRoot:   chanState.TapscriptRoot,
×
UNCOV
119
                CustomBlob:      chanState.CustomBlob,
×
UNCOV
120
        }
×
UNCOV
121
}
×
122

123
// CommitDiffAuxInput is the input required to compute the diff of the auxiliary
124
// leaves for a commitment transaction.
125
type CommitDiffAuxInput struct {
126
        // ChannelState is the static channel information of the channel this
127
        // commitment transaction relates to.
128
        ChannelState AuxChanState
129

130
        // PrevBlob is the blob of the previous commitment transaction.
131
        PrevBlob tlv.Blob
132

133
        // UnfilteredView is the unfiltered, original HTLC view of the channel.
134
        // Unfiltered in this context means that the view contains all HTLCs,
135
        // including the canceled ones.
136
        UnfilteredView *HtlcView
137

138
        // WhoseCommit denotes whose commitment transaction we are computing the
139
        // diff for.
140
        WhoseCommit lntypes.ChannelParty
141

142
        // OurBalance is the balance of the local party.
143
        OurBalance lnwire.MilliSatoshi
144

145
        // TheirBalance is the balance of the remote party.
146
        TheirBalance lnwire.MilliSatoshi
147

148
        // KeyRing is the key ring that can be used to derive keys for the
149
        // commitment transaction.
150
        KeyRing CommitmentKeyRing
151
}
152

153
// CommitDiffAuxResult is the result of computing the diff of the auxiliary
154
// leaves for a commitment transaction.
155
type CommitDiffAuxResult struct {
156
        // AuxLeaves are the auxiliary leaves for the new commitment
157
        // transaction.
158
        AuxLeaves fn.Option[CommitAuxLeaves]
159

160
        // CommitSortFunc is an optional function that sorts the commitment
161
        // transaction inputs and outputs.
162
        CommitSortFunc fn.Option[CommitSortFunc]
163
}
164

165
// AuxLeafStore is used to optionally fetch auxiliary tapscript leaves for the
166
// commitment transaction given an opaque blob. This is also used to implement
167
// a state transition function for the blobs to allow them to be refreshed with
168
// each state.
169
type AuxLeafStore interface {
170
        // FetchLeavesFromView attempts to fetch the auxiliary leaves that
171
        // correspond to the passed aux blob, and pending original (unfiltered)
172
        // HTLC view.
173
        FetchLeavesFromView(
174
                in CommitDiffAuxInput) fn.Result[CommitDiffAuxResult]
175

176
        // FetchLeavesFromCommit attempts to fetch the auxiliary leaves that
177
        // correspond to the passed aux blob, and an existing channel
178
        // commitment.
179
        FetchLeavesFromCommit(chanState AuxChanState,
180
                commit channeldb.ChannelCommitment,
181
                keyRing CommitmentKeyRing, whoseCommit lntypes.ChannelParty,
182
        ) fn.Result[CommitDiffAuxResult]
183

184
        // FetchLeavesFromRevocation attempts to fetch the auxiliary leaves
185
        // from a channel revocation that stores balance + blob information.
186
        FetchLeavesFromRevocation(
187
                r *channeldb.RevocationLog) fn.Result[CommitDiffAuxResult]
188

189
        // ApplyHtlcView serves as the state transition function for the custom
190
        // channel's blob. Given the old blob, and an HTLC view, then a new
191
        // blob should be returned that reflects the pending updates.
192
        ApplyHtlcView(in CommitDiffAuxInput) fn.Result[fn.Option[tlv.Blob]]
193
}
194

195
// auxLeavesFromView is used to derive the set of commit aux leaves (if any),
196
// that are needed to create a new commitment transaction using the original
197
// (unfiltered) htlc view.
198
func auxLeavesFromView(leafStore AuxLeafStore, chanState *channeldb.OpenChannel,
199
        prevBlob fn.Option[tlv.Blob], originalView *HtlcView,
200
        whoseCommit lntypes.ChannelParty, ourBalance,
201
        theirBalance lnwire.MilliSatoshi,
UNCOV
202
        keyRing CommitmentKeyRing) fn.Result[CommitDiffAuxResult] {
×
UNCOV
203

×
UNCOV
204
        return fn.MapOptionZ(
×
UNCOV
205
                prevBlob, func(blob tlv.Blob) fn.Result[CommitDiffAuxResult] {
×
206
                        return leafStore.FetchLeavesFromView(CommitDiffAuxInput{
×
207
                                ChannelState:   NewAuxChanState(chanState),
×
208
                                PrevBlob:       blob,
×
209
                                UnfilteredView: originalView,
×
210
                                WhoseCommit:    whoseCommit,
×
211
                                OurBalance:     ourBalance,
×
212
                                TheirBalance:   theirBalance,
×
213
                                KeyRing:        keyRing,
×
214
                        })
×
215
                },
×
216
        )
217
}
218

219
// updateAuxBlob is a helper function that attempts to update the aux blob
220
// given the prior and current state information.
221
func updateAuxBlob(leafStore AuxLeafStore, chanState *channeldb.OpenChannel,
222
        prevBlob fn.Option[tlv.Blob], nextViewUnfiltered *HtlcView,
223
        whoseCommit lntypes.ChannelParty, ourBalance,
224
        theirBalance lnwire.MilliSatoshi,
UNCOV
225
        keyRing CommitmentKeyRing) fn.Result[fn.Option[tlv.Blob]] {
×
UNCOV
226

×
UNCOV
227
        return fn.MapOptionZ(
×
UNCOV
228
                prevBlob, func(blob tlv.Blob) fn.Result[fn.Option[tlv.Blob]] {
×
229
                        return leafStore.ApplyHtlcView(CommitDiffAuxInput{
×
230
                                ChannelState:   NewAuxChanState(chanState),
×
231
                                PrevBlob:       blob,
×
232
                                UnfilteredView: nextViewUnfiltered,
×
233
                                WhoseCommit:    whoseCommit,
×
234
                                OurBalance:     ourBalance,
×
235
                                TheirBalance:   theirBalance,
×
236
                                KeyRing:        keyRing,
×
237
                        })
×
238
                },
×
239
        )
240
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc