dyn_commit.go
1 package lnwire 2 3 import ( 4 "bytes" 5 "io" 6 7 "github.com/btcsuite/btcd/btcutil" 8 "github.com/lightningnetwork/lnd/tlv" 9 ) 10 11 // DynCommit is a composite message that is used to irrefutably execute a 12 // dynamic commitment update. 13 type DynCommit struct { 14 // DynPropose is an embedded version of the original DynPropose message 15 // that initiated this negotiation. 16 DynPropose 17 18 // DynAck is an embedded version of the original DynAck message that 19 // countersigned this negotiation. 20 DynAck 21 22 // ExtraData is the set of data that was appended to this message to 23 // fill out the full maximum transport message size. These fields can 24 // be used to specify optional data such as custom TLV fields. 25 ExtraData ExtraOpaqueData 26 } 27 28 // A compile time check to ensure DynCommit implements the lnwire.Message 29 // interface. 30 var _ Message = (*DynCommit)(nil) 31 32 // A compile time check to ensure DynCommit implements the 33 // lnwire.SizeableMessage interface. 34 var _ SizeableMessage = (*DynCommit)(nil) 35 36 // Encode serializes the target DynAck into the passed io.Writer. Serialization 37 // will observe the rules defined by the passed protocol version. 38 // 39 // This is a part of the lnwire.Message interface. 40 func (dc *DynCommit) Encode(w *bytes.Buffer, _ uint32) error { 41 if err := WriteChannelID(w, dc.DynPropose.ChanID); err != nil { 42 return err 43 } 44 45 if err := WriteSig(w, dc.Sig); err != nil { 46 return err 47 } 48 49 // Create extra data records. 50 producers, err := dc.ExtraData.RecordProducers() 51 if err != nil { 52 return err 53 } 54 55 // Append the known records. 56 producers = append(producers, dynProposeRecords(&dc.DynPropose)...) 57 dc.LocalNonce.WhenSome( 58 func(rec tlv.RecordT[tlv.TlvType14, Musig2Nonce]) { 59 producers = append(producers, &rec) 60 }, 61 ) 62 63 // Encode all known records. 64 var tlvData ExtraOpaqueData 65 err = tlvData.PackRecords(producers...) 66 if err != nil { 67 return err 68 } 69 70 return WriteBytes(w, tlvData) 71 } 72 73 // Decode deserializes the serialized DynCommit stored in the passed io.Reader 74 // into the target DynAck using the deserialization rules defined by the passed 75 // protocol version. 76 // 77 // This is a part of the lnwire.Message interface. 78 func (dc *DynCommit) Decode(r io.Reader, _ uint32) error { 79 // Parse out main message. 80 if err := ReadElements(r, &dc.DynPropose.ChanID, &dc.Sig); err != nil { 81 return err 82 } 83 dc.DynAck.ChanID = dc.DynPropose.ChanID 84 85 // Parse out TLV records. 86 var tlvRecords ExtraOpaqueData 87 if err := ReadElement(r, &tlvRecords); err != nil { 88 return err 89 } 90 91 // Prepare receiving buffers to be filled by TLV extraction. 92 var dustLimit tlv.RecordT[tlv.TlvType0, tlv.BigSizeT[btcutil.Amount]] 93 var maxValue tlv.RecordT[tlv.TlvType2, MilliSatoshi] 94 var htlcMin tlv.RecordT[tlv.TlvType4, MilliSatoshi] 95 var reserve tlv.RecordT[tlv.TlvType6, tlv.BigSizeT[btcutil.Amount]] 96 csvDelay := dc.CsvDelay.Zero() 97 maxHtlcs := dc.MaxAcceptedHTLCs.Zero() 98 chanType := dc.ChannelType.Zero() 99 nonce := dc.LocalNonce.Zero() 100 101 // Parse all known records and extra data. 102 knownRecords, extraData, err := ParseAndExtractExtraData( 103 tlvRecords, &dustLimit, &maxValue, &htlcMin, &reserve, 104 &csvDelay, &maxHtlcs, &chanType, &nonce, 105 ) 106 if err != nil { 107 return err 108 } 109 110 // Check the results of the TLV Stream decoding and appropriately set 111 // message fields. 112 if _, ok := knownRecords[dc.DustLimit.TlvType()]; ok { 113 dc.DustLimit = tlv.SomeRecordT(dustLimit) 114 } 115 if _, ok := knownRecords[dc.MaxValueInFlight.TlvType()]; ok { 116 dc.MaxValueInFlight = tlv.SomeRecordT(maxValue) 117 } 118 if _, ok := knownRecords[dc.HtlcMinimum.TlvType()]; ok { 119 dc.HtlcMinimum = tlv.SomeRecordT(htlcMin) 120 } 121 if _, ok := knownRecords[dc.ChannelReserve.TlvType()]; ok { 122 dc.ChannelReserve = tlv.SomeRecordT(reserve) 123 } 124 if _, ok := knownRecords[dc.CsvDelay.TlvType()]; ok { 125 dc.CsvDelay = tlv.SomeRecordT(csvDelay) 126 } 127 if _, ok := knownRecords[dc.MaxAcceptedHTLCs.TlvType()]; ok { 128 dc.MaxAcceptedHTLCs = tlv.SomeRecordT(maxHtlcs) 129 } 130 if _, ok := knownRecords[dc.ChannelType.TlvType()]; ok { 131 dc.ChannelType = tlv.SomeRecordT(chanType) 132 } 133 if _, ok := knownRecords[dc.LocalNonce.TlvType()]; ok { 134 dc.LocalNonce = tlv.SomeRecordT(nonce) 135 } 136 137 dc.ExtraData = extraData 138 139 return nil 140 } 141 142 // MsgType returns the MessageType code which uniquely identifies this message 143 // as a DynCommit on the wire. 144 // 145 // This is part of the lnwire.Message interface. 146 func (dc *DynCommit) MsgType() MessageType { 147 return MsgDynCommit 148 } 149 150 // SerializedSize returns the serialized size of the message in bytes. 151 // 152 // This is part of the lnwire.SizeableMessage interface. 153 func (dc *DynCommit) SerializedSize() (uint32, error) { 154 return MessageSerializedSize(dc) 155 }