github.com/decred/dcrlnd@v0.7.6/lnwire/accept_channel.go (about) 1 package lnwire 2 3 import ( 4 "bytes" 5 "io" 6 7 "github.com/decred/dcrd/dcrec/secp256k1/v4" 8 "github.com/decred/dcrd/dcrutil/v4" 9 "github.com/decred/dcrlnd/tlv" 10 ) 11 12 // AcceptChannel is the message Bob sends to Alice after she initiates the 13 // single funder channel workflow via an AcceptChannel message. Once Alice 14 // receives Bob's response, then she has all the items necessary to construct 15 // the funding transaction, and both commitment transactions. 16 type AcceptChannel struct { 17 // PendingChannelID serves to uniquely identify the future channel 18 // created by the initiated single funder workflow. 19 PendingChannelID [32]byte 20 21 // DustLimit is the specific dust limit the sender of this message 22 // would like enforced on their version of the commitment transaction. 23 // Any output below this value will be "trimmed" from the commitment 24 // transaction, with the amount of the HTLC going to dust. 25 DustLimit dcrutil.Amount 26 27 // MaxValueInFlight represents the maximum amount of coins that can be 28 // pending within the channel at any given time. If the amount of funds 29 // in limbo exceeds this amount, then the channel will be failed. 30 MaxValueInFlight MilliAtom 31 32 // ChannelReserve is the amount of DCR that the receiving party MUST 33 // maintain a balance above at all times. This is a safety mechanism to 34 // ensure that both sides always have skin in the game during the 35 // channel's lifetime. 36 ChannelReserve dcrutil.Amount 37 38 // HtlcMinimum is the smallest HTLC that the sender of this message 39 // will accept. 40 HtlcMinimum MilliAtom 41 42 // MinAcceptDepth is the minimum depth that the initiator of the 43 // channel should wait before considering the channel open. 44 MinAcceptDepth uint32 45 46 // CsvDelay is the number of blocks to use for the relative time lock 47 // in the pay-to-self output of both commitment transactions. 48 CsvDelay uint16 49 50 // MaxAcceptedHTLCs is the total number of incoming HTLC's that the 51 // sender of this channel will accept. 52 // 53 // TODO(roasbeef): acks the initiator's, same with max in flight? 54 MaxAcceptedHTLCs uint16 55 56 // FundingKey is the key that should be used on behalf of the sender 57 // within the 2-of-2 multi-sig output that it contained within the 58 // funding transaction. 59 FundingKey *secp256k1.PublicKey 60 61 // RevocationPoint is the base revocation point for the sending party. 62 // Any commitment transaction belonging to the receiver of this message 63 // should use this key and their per-commitment point to derive the 64 // revocation key for the commitment transaction. 65 RevocationPoint *secp256k1.PublicKey 66 67 // PaymentPoint is the base payment point for the sending party. This 68 // key should be combined with the per commitment point for a 69 // particular commitment state in order to create the key that should 70 // be used in any output that pays directly to the sending party, and 71 // also within the HTLC covenant transactions. 72 PaymentPoint *secp256k1.PublicKey 73 74 // DelayedPaymentPoint is the delay point for the sending party. This 75 // key should be combined with the per commitment point to derive the 76 // keys that are used in outputs of the sender's commitment transaction 77 // where they claim funds. 78 DelayedPaymentPoint *secp256k1.PublicKey 79 80 // HtlcPoint is the base point used to derive the set of keys for this 81 // party that will be used within the HTLC public key scripts. This 82 // value is combined with the receiver's revocation base point in order 83 // to derive the keys that are used within HTLC scripts. 84 HtlcPoint *secp256k1.PublicKey 85 86 // FirstCommitmentPoint is the first commitment point for the sending 87 // party. This value should be combined with the receiver's revocation 88 // base point in order to derive the revocation keys that are placed 89 // within the commitment transaction of the sender. 90 FirstCommitmentPoint *secp256k1.PublicKey 91 92 // UpfrontShutdownScript is the script to which the channel funds should 93 // be paid when mutually closing the channel. This field is optional, and 94 // and has a length prefix, so a zero will be written if it is not set 95 // and its length followed by the script will be written if it is set. 96 UpfrontShutdownScript DeliveryAddress 97 98 // ChannelType is the explicit channel type the initiator wishes to 99 // open. 100 ChannelType *ChannelType 101 102 // LeaseExpiry represents the absolute expiration height of a channel 103 // lease. This is a custom TLV record that will only apply when a leased 104 // channel is being opened using the script enforced lease commitment 105 // type. 106 LeaseExpiry *LeaseExpiry 107 108 // ExtraData is the set of data that was appended to this message to 109 // fill out the full maximum transport message size. These fields can 110 // be used to specify optional data such as custom TLV fields. 111 // 112 // NOTE: Since the upfront shutdown script MUST be present (though can 113 // be zero-length) if any TLV data is available, the script will be 114 // extracted and removed from this blob when decoding. ExtraData will 115 // contain all TLV records _except_ the DeliveryAddress record in that 116 // case. 117 ExtraData ExtraOpaqueData 118 } 119 120 // A compile time check to ensure AcceptChannel implements the lnwire.Message 121 // interface. 122 var _ Message = (*AcceptChannel)(nil) 123 124 // Encode serializes the target AcceptChannel into the passed io.Writer 125 // implementation. Serialization will observe the rules defined by the passed 126 // protocol version. 127 // 128 // This is part of the lnwire.Message interface. 129 func (a *AcceptChannel) Encode(w *bytes.Buffer, pver uint32) error { 130 recordProducers := []tlv.RecordProducer{&a.UpfrontShutdownScript} 131 if a.ChannelType != nil { 132 recordProducers = append(recordProducers, a.ChannelType) 133 } 134 if a.LeaseExpiry != nil { 135 recordProducers = append(recordProducers, a.LeaseExpiry) 136 } 137 err := EncodeMessageExtraData(&a.ExtraData, recordProducers...) 138 if err != nil { 139 return err 140 } 141 142 if err := WriteBytes(w, a.PendingChannelID[:]); err != nil { 143 return err 144 } 145 146 if err := WriteSatoshi(w, a.DustLimit); err != nil { 147 return err 148 } 149 150 if err := WriteMilliAtom(w, a.MaxValueInFlight); err != nil { 151 return err 152 } 153 154 if err := WriteSatoshi(w, a.ChannelReserve); err != nil { 155 return err 156 } 157 158 if err := WriteMilliAtom(w, a.HtlcMinimum); err != nil { 159 return err 160 } 161 162 if err := WriteUint32(w, a.MinAcceptDepth); err != nil { 163 return err 164 } 165 166 if err := WriteUint16(w, a.CsvDelay); err != nil { 167 return err 168 } 169 170 if err := WriteUint16(w, a.MaxAcceptedHTLCs); err != nil { 171 return err 172 } 173 174 if err := WritePublicKey(w, a.FundingKey); err != nil { 175 return err 176 } 177 178 if err := WritePublicKey(w, a.RevocationPoint); err != nil { 179 return err 180 } 181 182 if err := WritePublicKey(w, a.PaymentPoint); err != nil { 183 return err 184 } 185 186 if err := WritePublicKey(w, a.DelayedPaymentPoint); err != nil { 187 return err 188 } 189 190 if err := WritePublicKey(w, a.HtlcPoint); err != nil { 191 return err 192 } 193 194 if err := WritePublicKey(w, a.FirstCommitmentPoint); err != nil { 195 return err 196 } 197 198 return WriteBytes(w, a.ExtraData) 199 } 200 201 // Decode deserializes the serialized AcceptChannel stored in the passed 202 // io.Reader into the target AcceptChannel using the deserialization rules 203 // defined by the passed protocol version. 204 // 205 // This is part of the lnwire.Message interface. 206 func (a *AcceptChannel) Decode(r io.Reader, pver uint32) error { 207 // Read all the mandatory fields in the accept message. 208 err := ReadElements(r, 209 a.PendingChannelID[:], 210 &a.DustLimit, 211 &a.MaxValueInFlight, 212 &a.ChannelReserve, 213 &a.HtlcMinimum, 214 &a.MinAcceptDepth, 215 &a.CsvDelay, 216 &a.MaxAcceptedHTLCs, 217 &a.FundingKey, 218 &a.RevocationPoint, 219 &a.PaymentPoint, 220 &a.DelayedPaymentPoint, 221 &a.HtlcPoint, 222 &a.FirstCommitmentPoint, 223 ) 224 if err != nil { 225 return err 226 } 227 228 // For backwards compatibility, the optional extra data blob for 229 // AcceptChannel must contain an entry for the upfront shutdown script. 230 // We'll read it out and attempt to parse it. 231 var tlvRecords ExtraOpaqueData 232 if err := ReadElements(r, &tlvRecords); err != nil { 233 return err 234 } 235 236 // Next we'll parse out the set of known records, keeping the raw tlv 237 // bytes untouched to ensure we don't drop any bytes erroneously. 238 var ( 239 chanType ChannelType 240 leaseExpiry LeaseExpiry 241 ) 242 typeMap, err := tlvRecords.ExtractRecords( 243 &a.UpfrontShutdownScript, &chanType, &leaseExpiry, 244 ) 245 if err != nil { 246 return err 247 } 248 249 // Set the corresponding TLV types if they were included in the stream. 250 if val, ok := typeMap[ChannelTypeRecordType]; ok && val == nil { 251 a.ChannelType = &chanType 252 } 253 if val, ok := typeMap[LeaseExpiryRecordType]; ok && val == nil { 254 a.LeaseExpiry = &leaseExpiry 255 } 256 257 a.ExtraData = tlvRecords 258 259 return nil 260 } 261 262 // MsgType returns the MessageType code which uniquely identifies this message 263 // as an AcceptChannel on the wire. 264 // 265 // This is part of the lnwire.Message interface. 266 func (a *AcceptChannel) MsgType() MessageType { 267 return MsgAcceptChannel 268 }