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

lightningnetwork / lnd / 15561477203

10 Jun 2025 01:54PM UTC coverage: 58.351% (-10.1%) from 68.487%
15561477203

Pull #9356

github

web-flow
Merge 6440b25db into c6d6d4c0b
Pull Request #9356: lnrpc: add incoming/outgoing channel ids filter to forwarding history request

33 of 36 new or added lines in 2 files covered. (91.67%)

28366 existing lines in 455 files now uncovered.

97715 of 167461 relevant lines covered (58.35%)

1.81 hits per line

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

0.0
/channeldb/migration27/channel.go
1
package migration27
2

3
import (
4
        "bytes"
5
        "fmt"
6

7
        lnwire "github.com/lightningnetwork/lnd/channeldb/migration/lnwire21"
8
        mig25 "github.com/lightningnetwork/lnd/channeldb/migration25"
9
        mig26 "github.com/lightningnetwork/lnd/channeldb/migration26"
10
        mig "github.com/lightningnetwork/lnd/channeldb/migration_01_to_11"
11
        "github.com/lightningnetwork/lnd/kvdb"
12
        "github.com/lightningnetwork/lnd/tlv"
13
)
14

15
const (
16
        // A tlv type definition used to serialize and deserialize a KeyLocator
17
        // from the database.
18
        keyLocType tlv.Type = 1
19

20
        // A tlv type used to serialize and deserialize the
21
        // `InitialLocalBalance` field.
22
        initialLocalBalanceType tlv.Type = 2
23

24
        // A tlv type used to serialize and deserialize the
25
        // `InitialRemoteBalance` field.
26
        initialRemoteBalanceType tlv.Type = 3
27
)
28

29
var (
30
        // chanInfoKey can be accessed within the bucket for a channel
31
        // (identified by its chanPoint). This key stores all the static
32
        // information for a channel which is decided at the end of  the
33
        // funding flow.
34
        chanInfoKey = []byte("chan-info-key")
35

36
        // localUpfrontShutdownKey can be accessed within the bucket for a
37
        // channel (identified by its chanPoint). This key stores an optional
38
        // upfront shutdown script for the local peer.
39
        localUpfrontShutdownKey = []byte("local-upfront-shutdown-key")
40

41
        // remoteUpfrontShutdownKey can be accessed within the bucket for a
42
        // channel (identified by its chanPoint). This key stores an optional
43
        // upfront shutdown script for the remote peer.
44
        remoteUpfrontShutdownKey = []byte("remote-upfront-shutdown-key")
45

46
        // lastWasRevokeKey is a key that stores true when the last update we
47
        // sent was a revocation and false when it was a commitment signature.
48
        // This is nil in the case of new channels with no updates exchanged.
49
        lastWasRevokeKey = []byte("last-was-revoke")
50

51
        // ErrNoChanInfoFound is returned when a particular channel does not
52
        // have any channels state.
53
        ErrNoChanInfoFound = fmt.Errorf("no chan info found")
54
)
55

56
// OpenChannel embeds a mig26.OpenChannel with the extra update-to-date
57
// serialization and deserialization methods.
58
//
59
// NOTE: doesn't have the Packager field as it's not used in current migration.
60
type OpenChannel struct {
61
        mig26.OpenChannel
62
}
63

64
// FetchChanInfo deserializes the channel info based on the legacy boolean.
UNCOV
65
func FetchChanInfo(chanBucket kvdb.RBucket, c *OpenChannel, legacy bool) error {
×
UNCOV
66
        infoBytes := chanBucket.Get(chanInfoKey)
×
UNCOV
67
        if infoBytes == nil {
×
68
                return ErrNoChanInfoFound
×
69
        }
×
UNCOV
70
        r := bytes.NewReader(infoBytes)
×
UNCOV
71

×
UNCOV
72
        var (
×
UNCOV
73
                chanType   mig.ChannelType
×
UNCOV
74
                chanStatus mig.ChannelStatus
×
UNCOV
75
        )
×
UNCOV
76

×
UNCOV
77
        if err := mig.ReadElements(r,
×
UNCOV
78
                &chanType, &c.ChainHash, &c.FundingOutpoint,
×
UNCOV
79
                &c.ShortChannelID, &c.IsPending, &c.IsInitiator,
×
UNCOV
80
                &chanStatus, &c.FundingBroadcastHeight,
×
UNCOV
81
                &c.NumConfsRequired, &c.ChannelFlags,
×
UNCOV
82
                &c.IdentityPub, &c.Capacity, &c.TotalMSatSent,
×
UNCOV
83
                &c.TotalMSatReceived,
×
UNCOV
84
        ); err != nil {
×
85
                return fmt.Errorf("ReadElements got: %w", err)
×
86
        }
×
87

UNCOV
88
        c.ChanType = mig25.ChannelType(chanType)
×
UNCOV
89
        c.ChanStatus = mig25.ChannelStatus(chanStatus)
×
UNCOV
90

×
UNCOV
91
        // For single funder channels that we initiated and have the funding
×
UNCOV
92
        // transaction to, read the funding txn.
×
UNCOV
93
        if c.FundingTxPresent() {
×
UNCOV
94
                if err := mig.ReadElement(r, &c.FundingTxn); err != nil {
×
UNCOV
95
                        return fmt.Errorf("read FundingTxn got: %w", err)
×
UNCOV
96
                }
×
97
        }
98

UNCOV
99
        if err := mig.ReadChanConfig(r, &c.LocalChanCfg); err != nil {
×
100
                return fmt.Errorf("read LocalChanCfg got: %w", err)
×
101
        }
×
UNCOV
102
        if err := mig.ReadChanConfig(r, &c.RemoteChanCfg); err != nil {
×
103
                return fmt.Errorf("read RemoteChanCfg got: %w", err)
×
104
        }
×
105

106
        // Retrieve the boolean stored under lastWasRevokeKey.
UNCOV
107
        lastWasRevokeBytes := chanBucket.Get(lastWasRevokeKey)
×
UNCOV
108
        if lastWasRevokeBytes == nil {
×
UNCOV
109
                // If nothing has been stored under this key, we store false in
×
UNCOV
110
                // the OpenChannel struct.
×
UNCOV
111
                c.LastWasRevoke = false
×
UNCOV
112
        } else {
×
113
                // Otherwise, read the value into the LastWasRevoke field.
×
114
                revokeReader := bytes.NewReader(lastWasRevokeBytes)
×
115
                err := mig.ReadElements(revokeReader, &c.LastWasRevoke)
×
116
                if err != nil {
×
117
                        return fmt.Errorf("read LastWasRevoke got: %w", err)
×
118
                }
×
119
        }
120

121
        // Make the tlv stream based on the legacy param.
UNCOV
122
        var (
×
UNCOV
123
                ts            *tlv.Stream
×
UNCOV
124
                err           error
×
UNCOV
125
                localBalance  uint64
×
UNCOV
126
                remoteBalance uint64
×
UNCOV
127
        )
×
UNCOV
128

×
UNCOV
129
        keyLocRecord := mig25.MakeKeyLocRecord(
×
UNCOV
130
                keyLocType, &c.RevocationKeyLocator,
×
UNCOV
131
        )
×
UNCOV
132

×
UNCOV
133
        // If it's legacy, create the stream with a single tlv record.
×
UNCOV
134
        if legacy {
×
UNCOV
135
                ts, err = tlv.NewStream(keyLocRecord)
×
UNCOV
136
        } else {
×
UNCOV
137
                // Otherwise, for the new format, we will encode the balance
×
UNCOV
138
                // fields in the tlv stream too.
×
UNCOV
139
                ts, err = tlv.NewStream(
×
UNCOV
140
                        keyLocRecord,
×
UNCOV
141
                        tlv.MakePrimitiveRecord(
×
UNCOV
142
                                initialLocalBalanceType, &localBalance,
×
UNCOV
143
                        ),
×
UNCOV
144
                        tlv.MakePrimitiveRecord(
×
UNCOV
145
                                initialRemoteBalanceType, &remoteBalance,
×
UNCOV
146
                        ),
×
UNCOV
147
                )
×
UNCOV
148
        }
×
UNCOV
149
        if err != nil {
×
150
                return fmt.Errorf("create tlv stream got: %w", err)
×
151
        }
×
152

UNCOV
153
        if err := ts.Decode(r); err != nil {
×
UNCOV
154
                return fmt.Errorf("decode tlv stream got: %w", err)
×
UNCOV
155
        }
×
156

157
        // For the new format, attach the balance fields.
UNCOV
158
        if !legacy {
×
UNCOV
159
                c.InitialLocalBalance = lnwire.MilliSatoshi(localBalance)
×
UNCOV
160
                c.InitialRemoteBalance = lnwire.MilliSatoshi(remoteBalance)
×
UNCOV
161
        }
×
162

163
        // Finally, read the optional shutdown scripts.
UNCOV
164
        if err := mig25.GetOptionalUpfrontShutdownScript(
×
UNCOV
165
                chanBucket, localUpfrontShutdownKey, &c.LocalShutdownScript,
×
UNCOV
166
        ); err != nil {
×
167
                return fmt.Errorf("local shutdown script got: %w", err)
×
168
        }
×
169

UNCOV
170
        return mig25.GetOptionalUpfrontShutdownScript(
×
UNCOV
171
                chanBucket, remoteUpfrontShutdownKey, &c.RemoteShutdownScript,
×
UNCOV
172
        )
×
173
}
174

175
// PutChanInfo serializes the channel info based on the legacy boolean.
UNCOV
176
func PutChanInfo(chanBucket kvdb.RwBucket, c *OpenChannel, legacy bool) error {
×
UNCOV
177
        var w bytes.Buffer
×
UNCOV
178
        if err := mig.WriteElements(&w,
×
UNCOV
179
                mig.ChannelType(c.ChanType), c.ChainHash, c.FundingOutpoint,
×
UNCOV
180
                c.ShortChannelID, c.IsPending, c.IsInitiator,
×
UNCOV
181
                mig.ChannelStatus(c.ChanStatus), c.FundingBroadcastHeight,
×
UNCOV
182
                c.NumConfsRequired, c.ChannelFlags,
×
UNCOV
183
                c.IdentityPub, c.Capacity, c.TotalMSatSent,
×
UNCOV
184
                c.TotalMSatReceived,
×
UNCOV
185
        ); err != nil {
×
186
                return err
×
187
        }
×
188

189
        // For single funder channels that we initiated, and we have the
190
        // funding transaction, then write the funding txn.
UNCOV
191
        if c.FundingTxPresent() {
×
UNCOV
192
                if err := mig.WriteElement(&w, c.FundingTxn); err != nil {
×
193
                        return err
×
194
                }
×
195
        }
196

UNCOV
197
        if err := mig.WriteChanConfig(&w, &c.LocalChanCfg); err != nil {
×
198
                return err
×
199
        }
×
UNCOV
200
        if err := mig.WriteChanConfig(&w, &c.RemoteChanCfg); err != nil {
×
201
                return err
×
202
        }
×
203

204
        // Make the tlv stream based on the legacy param.
UNCOV
205
        tlvStream, err := mig26.MakeTlvStream(&c.OpenChannel, legacy)
×
UNCOV
206
        if err != nil {
×
207
                return err
×
208
        }
×
209

UNCOV
210
        if err := tlvStream.Encode(&w); err != nil {
×
211
                return err
×
212
        }
×
213

UNCOV
214
        if err := chanBucket.Put(chanInfoKey, w.Bytes()); err != nil {
×
215
                return err
×
216
        }
×
217

218
        // Finally, add optional shutdown scripts for the local and remote peer
219
        // if they are present.
UNCOV
220
        if err := mig25.PutOptionalUpfrontShutdownScript(
×
UNCOV
221
                chanBucket, localUpfrontShutdownKey, c.LocalShutdownScript,
×
UNCOV
222
        ); err != nil {
×
223
                return err
×
224
        }
×
225

UNCOV
226
        return mig25.PutOptionalUpfrontShutdownScript(
×
UNCOV
227
                chanBucket, remoteUpfrontShutdownKey, c.RemoteShutdownScript,
×
UNCOV
228
        )
×
229
}
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