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

lightningnetwork / lnd / 15951470896

29 Jun 2025 04:23AM UTC coverage: 67.594% (-0.01%) from 67.606%
15951470896

Pull #9751

github

web-flow
Merge 599d9b051 into 6290edf14
Pull Request #9751: multi: update Go to 1.23.10 and update some packages

135088 of 199851 relevant lines covered (67.59%)

21909.44 hits per line

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

74.63
/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.
65
func FetchChanInfo(chanBucket kvdb.RBucket, c *OpenChannel, legacy bool) error {
8✔
66
        infoBytes := chanBucket.Get(chanInfoKey)
8✔
67
        if infoBytes == nil {
8✔
68
                return ErrNoChanInfoFound
×
69
        }
×
70
        r := bytes.NewReader(infoBytes)
8✔
71

8✔
72
        var (
8✔
73
                chanType   mig.ChannelType
8✔
74
                chanStatus mig.ChannelStatus
8✔
75
        )
8✔
76

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

88
        c.ChanType = mig25.ChannelType(chanType)
8✔
89
        c.ChanStatus = mig25.ChannelStatus(chanStatus)
8✔
90

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

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

106
        // Retrieve the boolean stored under lastWasRevokeKey.
107
        lastWasRevokeBytes := chanBucket.Get(lastWasRevokeKey)
7✔
108
        if lastWasRevokeBytes == nil {
14✔
109
                // If nothing has been stored under this key, we store false in
7✔
110
                // the OpenChannel struct.
7✔
111
                c.LastWasRevoke = false
7✔
112
        } else {
7✔
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.
122
        var (
7✔
123
                ts            *tlv.Stream
7✔
124
                err           error
7✔
125
                localBalance  uint64
7✔
126
                remoteBalance uint64
7✔
127
        )
7✔
128

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

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

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

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

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

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

175
// PutChanInfo serializes the channel info based on the legacy boolean.
176
func PutChanInfo(chanBucket kvdb.RwBucket, c *OpenChannel, legacy bool) error {
6✔
177
        var w bytes.Buffer
6✔
178
        if err := mig.WriteElements(&w,
6✔
179
                mig.ChannelType(c.ChanType), c.ChainHash, c.FundingOutpoint,
6✔
180
                c.ShortChannelID, c.IsPending, c.IsInitiator,
6✔
181
                mig.ChannelStatus(c.ChanStatus), c.FundingBroadcastHeight,
6✔
182
                c.NumConfsRequired, c.ChannelFlags,
6✔
183
                c.IdentityPub, c.Capacity, c.TotalMSatSent,
6✔
184
                c.TotalMSatReceived,
6✔
185
        ); err != nil {
6✔
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.
191
        if c.FundingTxPresent() {
9✔
192
                if err := mig.WriteElement(&w, c.FundingTxn); err != nil {
3✔
193
                        return err
×
194
                }
×
195
        }
196

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

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

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

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

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

226
        return mig25.PutOptionalUpfrontShutdownScript(
6✔
227
                chanBucket, remoteUpfrontShutdownKey, c.RemoteShutdownScript,
6✔
228
        )
6✔
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