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

lightningnetwork / lnd / 11216766535

07 Oct 2024 01:37PM UTC coverage: 57.817% (-1.0%) from 58.817%
11216766535

Pull #9148

github

ProofOfKeags
lnwire: remove kickoff feerate from propose/commit
Pull Request #9148: DynComms [2/n]: lnwire: add authenticated wire messages for Dyn*

571 of 879 new or added lines in 16 files covered. (64.96%)

23253 existing lines in 251 files now uncovered.

99022 of 171268 relevant lines covered (57.82%)

38420.67 hits per line

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

57.58
/lnwire/dyn_ack.go
1
package lnwire
2

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

8
        "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
9
        "github.com/btcsuite/btcd/chaincfg/chainhash"
10
        "github.com/decred/dcrd/dcrec/secp256k1/v4"
11
        "github.com/lightningnetwork/lnd/fn"
12
        "github.com/lightningnetwork/lnd/tlv"
13
)
14

15
const (
16
        // DALocalMusig2Pubnonce is the TLV type number that identifies the
17
        // musig2 public nonce that we need to verify the commitment transaction
18
        // signature.
19
        DALocalMusig2Pubnonce tlv.Type = 0
20
)
21

22
// DynAck is the message used to accept the parameters of a dynamic commitment
23
// negotiation. Additional optional parameters will need to be present depending
24
// on the details of the dynamic commitment upgrade.
25
type DynAck struct {
26
        // ChanID is the ChannelID of the channel that is currently undergoing
27
        // a dynamic commitment negotiation
28
        ChanID ChannelID
29

30
        // Sig is a signature that acknowledges and approves the parameters
31
        // that were requested in the DynPropose
32
        Sig Sig
33

34
        // LocalNonce is an optional field that is transmitted when accepting
35
        // a dynamic commitment upgrade to Taproot Channels. This nonce will be
36
        // used to verify the first commitment transaction signature. This will
37
        // only be populated if the DynPropose we are responding to specifies
38
        // taproot channels in the ChannelType field.
39
        LocalNonce fn.Option[Musig2Nonce]
40

41
        // ExtraData is the set of data that was appended to this message to
42
        // fill out the full maximum transport message size. These fields can
43
        // be used to specify optional data such as custom TLV fields.
44
        ExtraData ExtraOpaqueData
45
}
46

47
// A compile time check to ensure DynAck implements the lnwire.Message
48
// interface.
49
var _ Message = (*DynAck)(nil)
50

51
// Encode serializes the target DynAck into the passed io.Writer. Serialization
52
// will observe the rules defined by the passed protocol version.
53
//
54
// This is a part of the lnwire.Message interface.
55
func (da *DynAck) Encode(w *bytes.Buffer, _ uint32) error {
100✔
56
        if err := WriteChannelID(w, da.ChanID); err != nil {
100✔
57
                return err
×
58
        }
×
59

60
        if err := WriteSig(w, da.Sig); err != nil {
100✔
NEW
61
                return err
×
NEW
62
        }
×
63

64
        var tlvRecords []tlv.Record
100✔
65
        da.LocalNonce.WhenSome(func(nonce Musig2Nonce) {
148✔
66
                tlvRecords = append(
48✔
67
                        tlvRecords, tlv.MakeStaticRecord(
48✔
68
                                DALocalMusig2Pubnonce, &nonce,
48✔
69
                                musig2.PubNonceSize, nonceTypeEncoder,
48✔
70
                                nonceTypeDecoder,
48✔
71
                        ),
48✔
72
                )
48✔
73
        })
48✔
74
        tlv.SortRecords(tlvRecords)
100✔
75

100✔
76
        tlvStream, err := tlv.NewStream(tlvRecords...)
100✔
77
        if err != nil {
100✔
78
                return err
×
79
        }
×
80

81
        var extraBytesWriter bytes.Buffer
100✔
82
        if err := tlvStream.Encode(&extraBytesWriter); err != nil {
100✔
83
                return err
×
84
        }
×
85

86
        da.ExtraData = ExtraOpaqueData(extraBytesWriter.Bytes())
100✔
87

100✔
88
        return WriteBytes(w, da.ExtraData)
100✔
89
}
90

91
// Decode deserializes the serialized DynAck stored in the passed io.Reader into
92
// the target DynAck using the deserialization rules defined by the passed
93
// protocol version.
94
//
95
// This is a part of the lnwire.Message interface.
96
func (da *DynAck) Decode(r io.Reader, _ uint32) error {
154✔
97
        // Parse out main message.
154✔
98
        if err := ReadElements(r, &da.ChanID, &da.Sig); err != nil {
185✔
99
                return err
31✔
100
        }
31✔
101

102
        // Parse out TLV records.
103
        var tlvRecords ExtraOpaqueData
123✔
104
        if err := ReadElement(r, &tlvRecords); err != nil {
123✔
105
                return err
×
106
        }
×
107

108
        // Prepare receiving buffers to be filled by TLV extraction.
109
        var localNonceScratch Musig2Nonce
123✔
110
        localNonce := tlv.MakeStaticRecord(
123✔
111
                DALocalMusig2Pubnonce, &localNonceScratch, musig2.PubNonceSize,
123✔
112
                nonceTypeEncoder, nonceTypeDecoder,
123✔
113
        )
123✔
114

123✔
115
        // Create set of Records to read TLV bytestream into.
123✔
116
        records := []tlv.Record{localNonce}
123✔
117
        tlv.SortRecords(records)
123✔
118

123✔
119
        // Read TLV stream into record set.
123✔
120
        extraBytesReader := bytes.NewReader(tlvRecords)
123✔
121
        tlvStream, err := tlv.NewStream(records...)
123✔
122
        if err != nil {
123✔
123
                return err
×
124
        }
×
125
        typeMap, err := tlvStream.DecodeWithParsedTypesP2P(extraBytesReader)
123✔
126
        if err != nil {
146✔
127
                return err
23✔
128
        }
23✔
129

130
        // Check the results of the TLV Stream decoding and appropriately set
131
        // message fields.
132
        if val, ok := typeMap[DALocalMusig2Pubnonce]; ok && val == nil {
148✔
133
                da.LocalNonce = fn.Some(localNonceScratch)
48✔
134
        }
48✔
135

136
        if len(tlvRecords) != 0 {
148✔
137
                da.ExtraData = tlvRecords
48✔
138
        }
48✔
139

140
        return nil
100✔
141
}
142

143
// MsgType returns the MessageType code which uniquely identifies this message
144
// as a DynAck on the wire.
145
//
146
// This is part of the lnwire.Message interface.
147
func (da *DynAck) MsgType() MessageType {
100✔
148
        return MsgDynAck
100✔
149
}
100✔
150

151
// Validate does DynAck signature validation for a given prior DynPropose
152
// message.
153
func (da *DynAck) Validate(propose DynPropose, nextHeight uint64,
NEW
154
        pubkey *secp256k1.PublicKey) error {
×
NEW
155

×
NEW
156
        cSig, err := da.Sig.ToSignature()
×
NEW
157
        if err != nil {
×
NEW
158
                return err
×
NEW
159
        }
×
160

NEW
161
        var msg bytes.Buffer
×
NEW
162
        err = WriteChannelID(&msg, da.ChanID)
×
NEW
163
        if err != nil {
×
NEW
164
                return err
×
NEW
165
        }
×
166

NEW
167
        err = WriteElement(&msg, nextHeight)
×
NEW
168
        if err != nil {
×
NEW
169
                return err
×
NEW
170
        }
×
171

NEW
172
        tlvData, err := propose.SerializeTlvData()
×
NEW
173
        if err != nil {
×
NEW
174
                return err
×
NEW
175
        }
×
176

NEW
177
        msg.Write(tlvData)
×
NEW
178

×
NEW
179
        digest := chainhash.DoubleHashB(msg.Bytes())
×
NEW
180

×
NEW
181
        if !cSig.Verify(digest, pubkey) {
×
NEW
182
                return fmt.Errorf(
×
NEW
183
                        "invalid signature for dyn_ack: %v @ %v by %v",
×
NEW
184
                        propose, nextHeight, pubkey,
×
NEW
185
                )
×
NEW
186
        }
×
187

NEW
188
        return nil
×
189
}
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