Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,6 @@ coverage.txt
/lnd-*/

.aider*

# All test data generated from rapid.
*/testdata
10 changes: 9 additions & 1 deletion lnwire/dyn_ack.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ type DynAck struct {
// a dynamic commitment negotiation
ChanID ChannelID

// Sig is a signature that acknowledges and approves the parameters
// that were requested in the DynPropose
Sig Sig

// LocalNonce is an optional field that is transmitted when accepting
// a dynamic commitment upgrade to Taproot Channels. This nonce will be
// used to verify the first commitment transaction signature. This will
Expand Down Expand Up @@ -54,6 +58,10 @@ func (da *DynAck) Encode(w *bytes.Buffer, _ uint32) error {
return err
}

if err := WriteSig(w, da.Sig); err != nil {
return err
}

var tlvRecords []tlv.Record
da.LocalNonce.WhenSome(func(nonce Musig2Nonce) {
tlvRecords = append(
Expand Down Expand Up @@ -88,7 +96,7 @@ func (da *DynAck) Encode(w *bytes.Buffer, _ uint32) error {
// This is a part of the lnwire.Message interface.
func (da *DynAck) Decode(r io.Reader, _ uint32) error {
// Parse out main message.
if err := ReadElements(r, &da.ChanID); err != nil {
if err := ReadElements(r, &da.ChanID, &da.Sig); err != nil {
return err
}

Expand Down
146 changes: 146 additions & 0 deletions lnwire/dyn_commit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package lnwire

import (
"bytes"
"io"

"github.com/btcsuite/btcd/btcutil"
"github.com/lightningnetwork/lnd/tlv"
)

// DynCommit is a composite message that is used to irrefutably execute a
// dynamic commitment update.
type DynCommit struct {
Comment thread
ProofOfKeags marked this conversation as resolved.
// DynPropose is an embedded version of the original DynPropose message
// that initiated this negotiation.
DynPropose

// DynAck is an embedded version of the original DynAck message that
// countersigned this negotiation.
DynAck

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

// A compile time check to ensure DynCommit implements the lnwire.Message
// interface.
var _ Message = (*DynCommit)(nil)

// A compile time check to ensure DynCommit implements the
// lnwire.SizeableMessage interface.
var _ SizeableMessage = (*DynCommit)(nil)

// Encode serializes the target DynAck into the passed io.Writer. Serialization
// will observe the rules defined by the passed protocol version.
//
// This is a part of the lnwire.Message interface.
func (dc *DynCommit) Encode(w *bytes.Buffer, _ uint32) error {
if err := WriteChannelID(w, dc.DynPropose.ChanID); err != nil {
return err
}

if err := WriteSig(w, dc.Sig); err != nil {
return err
}

var extra ExtraOpaqueData
err := extra.PackRecords(dynProposeRecords(&dc.DynPropose)...)
if err != nil {
return err
}
dc.ExtraData = extra

return WriteBytes(w, dc.ExtraData)
}

// Decode deserializes the serialized DynCommit stored in the passed io.Reader
// into the target DynAck using the deserialization rules defined by the passed
// protocol version.
//
// This is a part of the lnwire.Message interface.
func (dc *DynCommit) Decode(r io.Reader, _ uint32) error {
// Parse out main message.
if err := ReadElements(r, &dc.DynPropose.ChanID, &dc.Sig); err != nil {
return err
}
dc.DynAck.ChanID = dc.DynPropose.ChanID

// Parse out TLV records.
var tlvRecords ExtraOpaqueData
if err := ReadElement(r, &tlvRecords); err != nil {
return err
}

// Prepare receiving buffers to be filled by TLV extraction.
var dustLimit tlv.RecordT[tlv.TlvType0, uint64]
var maxValue tlv.RecordT[tlv.TlvType2, uint64]
var htlcMin tlv.RecordT[tlv.TlvType4, uint64]
var reserve tlv.RecordT[tlv.TlvType6, uint64]
csvDelay := dc.CsvDelay.Zero()
maxHtlcs := dc.MaxAcceptedHTLCs.Zero()
chanType := dc.ChannelType.Zero()

typeMap, err := tlvRecords.ExtractRecords(
&dustLimit, &maxValue, &htlcMin, &reserve, &csvDelay, &maxHtlcs,
&chanType,
)
if err != nil {
return err
}

// Check the results of the TLV Stream decoding and appropriately set
// message fields.
if val, ok := typeMap[dc.DustLimit.TlvType()]; ok && val == nil {
var rec tlv.RecordT[tlv.TlvType0, btcutil.Amount]
rec.Val = btcutil.Amount(dustLimit.Val)
dc.DustLimit = tlv.SomeRecordT(rec)
}
if val, ok := typeMap[dc.MaxValueInFlight.TlvType()]; ok && val == nil {
var rec tlv.RecordT[tlv.TlvType2, MilliSatoshi]
rec.Val = MilliSatoshi(maxValue.Val)
dc.MaxValueInFlight = tlv.SomeRecordT(rec)
}
if val, ok := typeMap[dc.HtlcMinimum.TlvType()]; ok && val == nil {
var rec tlv.RecordT[tlv.TlvType4, MilliSatoshi]
rec.Val = MilliSatoshi(htlcMin.Val)
dc.HtlcMinimum = tlv.SomeRecordT(rec)
}
if val, ok := typeMap[dc.ChannelReserve.TlvType()]; ok && val == nil {
var rec tlv.RecordT[tlv.TlvType6, btcutil.Amount]
rec.Val = btcutil.Amount(reserve.Val)
dc.ChannelReserve = tlv.SomeRecordT(rec)
}
if val, ok := typeMap[dc.CsvDelay.TlvType()]; ok && val == nil {
dc.CsvDelay = tlv.SomeRecordT(csvDelay)
}
if val, ok := typeMap[dc.MaxAcceptedHTLCs.TlvType()]; ok && val == nil {
dc.MaxAcceptedHTLCs = tlv.SomeRecordT(maxHtlcs)
}
if val, ok := typeMap[dc.ChannelType.TlvType()]; ok && val == nil {
dc.ChannelType = tlv.SomeRecordT(chanType)
}

if len(tlvRecords) != 0 {
dc.ExtraData = tlvRecords
}

return nil
}

// MsgType returns the MessageType code which uniquely identifies this message
// as a DynCommit on the wire.
//
// This is part of the lnwire.Message interface.
func (dc *DynCommit) MsgType() MessageType {
return MsgDynCommit
}

// SerializedSize returns the serialized size of the message in bytes.
//
// This is part of the lnwire.SizeableMessage interface.
func (dc *DynCommit) SerializedSize() (uint32, error) {
return MessageSerializedSize(dc)
}
Loading
Loading