github.com/decred/dcrlnd@v0.7.6/channeldb/migration_01_to_11/channel.go (about) 1 package migration_01_to_11 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "strconv" 8 "strings" 9 "sync" 10 11 "github.com/decred/dcrd/chaincfg/chainhash" 12 "github.com/decred/dcrd/dcrec/secp256k1/v4" 13 "github.com/decred/dcrd/dcrutil/v4" 14 "github.com/decred/dcrd/wire" 15 lnwire "github.com/decred/dcrlnd/channeldb/migration/lnwire21" 16 "github.com/decred/dcrlnd/keychain" 17 "github.com/decred/dcrlnd/shachain" 18 ) 19 20 var ( 21 // closedChannelBucket stores summarization information concerning 22 // previously open, but now closed channels. 23 closedChannelBucket = []byte("closed-chan-bucket") 24 25 // openChanBucket stores all the currently open channels. This bucket 26 // has a second, nested bucket which is keyed by a node's ID. Within 27 // that node ID bucket, all attributes required to track, update, and 28 // close a channel are stored. 29 // 30 // openChan -> nodeID -> chanPoint 31 // 32 // TODO(roasbeef): flesh out comment 33 openChannelBucket = []byte("open-chan-bucket") 34 ) 35 36 // ChannelType is an enum-like type that describes one of several possible 37 // channel types. Each open channel is associated with a particular type as the 38 // channel type may determine how higher level operations are conducted such as 39 // fee negotiation, channel closing, the format of HTLCs, etc. Structure-wise, 40 // a ChannelType is a bit field, with each bit denoting a modification from the 41 // base channel type of single funder. 42 type ChannelType uint8 43 44 const ( 45 // NOTE: iota isn't used here for this enum needs to be stable 46 // long-term as it will be persisted to the database. 47 48 // SingleFunderBit represents a channel wherein one party solely funds 49 // the entire capacity of the channel. 50 SingleFunderBit ChannelType = 0 51 ) 52 53 // ChannelConstraints represents a set of constraints meant to allow a node to 54 // limit their exposure, enact flow control and ensure that all HTLCs are 55 // economically relevant. This struct will be mirrored for both sides of the 56 // channel, as each side will enforce various constraints that MUST be adhered 57 // to for the life time of the channel. The parameters for each of these 58 // constraints are static for the duration of the channel, meaning the channel 59 // must be torn down for them to change. 60 type ChannelConstraints struct { 61 // DustLimit is the threhsold (in atoms) below which any outputs 62 // should be trimmed. When an output is trimmed, it isn't materialized 63 // as an actual output, but is instead burned to miner's fees. 64 DustLimit dcrutil.Amount 65 66 // ChanReserve is an absolute reservation on the channel for the 67 // owner of this set of constraints. This means that the current 68 // settled balance for this node CANNOT dip below the reservation 69 // amount. This acts as a defense against costless attacks when 70 // either side no longer has any skin in the game. 71 ChanReserve dcrutil.Amount 72 73 // MaxPendingAmount is the maximum pending HTLC value that the 74 // owner of these constraints can offer the remote node at a 75 // particular time. 76 MaxPendingAmount lnwire.MilliAtom 77 78 // MinHTLC is the minimum HTLC value that the owner of these 79 // constraints can offer the remote node. If any HTLCs below this 80 // amount are offered, then the HTLC will be rejected. This, in 81 // tandem with the dust limit allows a node to regulate the 82 // smallest HTLC that it deems economically relevant. 83 MinHTLC lnwire.MilliAtom 84 85 // MaxAcceptedHtlcs is the maximum number of HTLCs that the owner of 86 // this set of constraints can offer the remote node. This allows each 87 // node to limit their over all exposure to HTLCs that may need to be 88 // acted upon in the case of a unilateral channel closure or a contract 89 // breach. 90 MaxAcceptedHtlcs uint16 91 92 // CsvDelay is the relative time lock delay expressed in blocks. Any 93 // settled outputs that pay to the owner of this channel configuration 94 // MUST ensure that the delay branch uses this value as the relative 95 // time lock. Similarly, any HTLC's offered by this node should use 96 // this value as well. 97 CsvDelay uint16 98 } 99 100 // ChannelConfig is a struct that houses the various configuration opens for 101 // channels. Each side maintains an instance of this configuration file as it 102 // governs: how the funding and commitment transaction to be created, the 103 // nature of HTLC's allotted, the keys to be used for delivery, and relative 104 // time lock parameters. 105 type ChannelConfig struct { 106 // ChannelConstraints is the set of constraints that must be upheld for 107 // the duration of the channel for the owner of this channel 108 // configuration. Constraints govern a number of flow control related 109 // parameters, also including the smallest HTLC that will be accepted 110 // by a participant. 111 ChannelConstraints 112 113 // MultiSigKey is the key to be used within the 2-of-2 output script 114 // for the owner of this channel config. 115 MultiSigKey keychain.KeyDescriptor 116 117 // RevocationBasePoint is the base public key to be used when deriving 118 // revocation keys for the remote node's commitment transaction. This 119 // will be combined along with a per commitment secret to derive a 120 // unique revocation key for each state. 121 RevocationBasePoint keychain.KeyDescriptor 122 123 // PaymentBasePoint is the base public key to be used when deriving 124 // the key used within the non-delayed pay-to-self output on the 125 // commitment transaction for a node. This will be combined with a 126 // tweak derived from the per-commitment point to ensure unique keys 127 // for each commitment transaction. 128 PaymentBasePoint keychain.KeyDescriptor 129 130 // DelayBasePoint is the base public key to be used when deriving the 131 // key used within the delayed pay-to-self output on the commitment 132 // transaction for a node. This will be combined with a tweak derived 133 // from the per-commitment point to ensure unique keys for each 134 // commitment transaction. 135 DelayBasePoint keychain.KeyDescriptor 136 137 // HtlcBasePoint is the base public key to be used when deriving the 138 // local HTLC key. The derived key (combined with the tweak derived 139 // from the per-commitment point) is used within the "to self" clause 140 // within any HTLC output scripts. 141 HtlcBasePoint keychain.KeyDescriptor 142 } 143 144 // ChannelCommitment is a snapshot of the commitment state at a particular 145 // point in the commitment chain. With each state transition, a snapshot of the 146 // current state along with all non-settled HTLCs are recorded. These snapshots 147 // detail the state of the _remote_ party's commitment at a particular state 148 // number. For ourselves (the local node) we ONLY store our most recent 149 // (unrevoked) state for safety purposes. 150 type ChannelCommitment struct { 151 // CommitHeight is the update number that this ChannelDelta represents 152 // the total number of commitment updates to this point. This can be 153 // viewed as sort of a "commitment height" as this number is 154 // monotonically increasing. 155 CommitHeight uint64 156 157 // LocalLogIndex is the cumulative log index index of the local node at 158 // this point in the commitment chain. This value will be incremented 159 // for each _update_ added to the local update log. 160 LocalLogIndex uint64 161 162 // LocalHtlcIndex is the current local running HTLC index. This value 163 // will be incremented for each outgoing HTLC the local node offers. 164 LocalHtlcIndex uint64 165 166 // RemoteLogIndex is the cumulative log index index of the remote node 167 // at this point in the commitment chain. This value will be 168 // incremented for each _update_ added to the remote update log. 169 RemoteLogIndex uint64 170 171 // RemoteHtlcIndex is the current remote running HTLC index. This value 172 // will be incremented for each outgoing HTLC the remote node offers. 173 RemoteHtlcIndex uint64 174 175 // LocalBalance is the current available settled balance within the 176 // channel directly spendable by us. 177 LocalBalance lnwire.MilliAtom 178 179 // RemoteBalance is the current available settled balance within the 180 // channel directly spendable by the remote node. 181 RemoteBalance lnwire.MilliAtom 182 183 // CommitFee is the amount calculated to be paid in fees for the 184 // current set of commitment transactions. The fee amount is persisted 185 // with the channel in order to allow the fee amount to be removed and 186 // recalculated with each channel state update, including updates that 187 // happen after a system restart. 188 CommitFee dcrutil.Amount 189 190 // FeePerKB is the min atoms/kilobyte that should be paid within the 191 // commitment transaction for the entire duration of the channel's 192 // lifetime. This field may be updated during normal operation of the 193 // channel as on-chain conditions change. 194 // 195 // TODO(halseth): make this AtomsPerKByte. Cannot be done atm because 196 // this will cause the import cycle lnwallet<->channeldb. Fee 197 // estimation stuff should be in its own package. 198 FeePerKB dcrutil.Amount 199 200 // CommitTx is the latest version of the commitment state, broadcast 201 // able by us. 202 CommitTx *wire.MsgTx 203 204 // CommitSig is one half of the signature required to fully complete 205 // the script for the commitment transaction above. This is the 206 // signature signed by the remote party for our version of the 207 // commitment transactions. 208 CommitSig []byte 209 210 // Htlcs is the set of HTLC's that are pending at this particular 211 // commitment height. 212 Htlcs []HTLC 213 214 // TODO(roasbeef): pending commit pointer? 215 // * lets just walk through 216 } 217 218 // ChannelStatus is a bit vector used to indicate whether an OpenChannel is in 219 // the default usable state, or a state where it shouldn't be used. 220 type ChannelStatus uint8 221 222 var ( 223 // ChanStatusDefault is the normal state of an open channel. 224 ChanStatusDefault ChannelStatus 225 226 // ChanStatusBorked indicates that the channel has entered an 227 // irreconcilable state, triggered by a state desynchronization or 228 // channel breach. Channels in this state should never be added to the 229 // htlc switch. 230 ChanStatusBorked ChannelStatus = 1 231 232 // ChanStatusCommitBroadcasted indicates that a commitment for this 233 // channel has been broadcasted. 234 ChanStatusCommitBroadcasted ChannelStatus = 1 << 1 235 236 // ChanStatusLocalDataLoss indicates that we have lost channel state 237 // for this channel, and broadcasting our latest commitment might be 238 // considered a breach. 239 // 240 // TODO(halseh): actually enforce that we are not force closing such a 241 // channel. 242 ChanStatusLocalDataLoss ChannelStatus = 1 << 2 243 244 // ChanStatusRestored is a status flag that signals that the channel 245 // has been restored, and doesn't have all the fields a typical channel 246 // will have. 247 ChanStatusRestored ChannelStatus = 1 << 3 248 ) 249 250 // chanStatusStrings maps a ChannelStatus to a human friendly string that 251 // describes that status. 252 var chanStatusStrings = map[ChannelStatus]string{ 253 ChanStatusDefault: "ChanStatusDefault", 254 ChanStatusBorked: "ChanStatusBorked", 255 ChanStatusCommitBroadcasted: "ChanStatusCommitBroadcasted", 256 ChanStatusLocalDataLoss: "ChanStatusLocalDataLoss", 257 ChanStatusRestored: "ChanStatusRestored", 258 } 259 260 // orderedChanStatusFlags is an in-order list of all that channel status flags. 261 var orderedChanStatusFlags = []ChannelStatus{ 262 ChanStatusDefault, 263 ChanStatusBorked, 264 ChanStatusCommitBroadcasted, 265 ChanStatusLocalDataLoss, 266 ChanStatusRestored, 267 } 268 269 // String returns a human-readable representation of the ChannelStatus. 270 func (c ChannelStatus) String() string { 271 // If no flags are set, then this is the default case. 272 if c == 0 { 273 return chanStatusStrings[ChanStatusDefault] 274 } 275 276 // Add individual bit flags. 277 statusStr := "" 278 for _, flag := range orderedChanStatusFlags { 279 if c&flag == flag { 280 statusStr += chanStatusStrings[flag] + "|" 281 c -= flag 282 } 283 } 284 285 // Remove anything to the right of the final bar, including it as well. 286 statusStr = strings.TrimRight(statusStr, "|") 287 288 // Add any remaining flags which aren't accounted for as hex. 289 if c != 0 { 290 statusStr += "|0x" + strconv.FormatUint(uint64(c), 16) 291 } 292 293 // If this was purely an unknown flag, then remove the extra bar at the 294 // start of the string. 295 statusStr = strings.TrimLeft(statusStr, "|") 296 297 return statusStr 298 } 299 300 // OpenChannel encapsulates the persistent and dynamic state of an open channel 301 // with a remote node. An open channel supports several options for on-disk 302 // serialization depending on the exact context. Full (upon channel creation) 303 // state commitments, and partial (due to a commitment update) writes are 304 // supported. Each partial write due to a state update appends the new update 305 // to an on-disk log, which can then subsequently be queried in order to 306 // "time-travel" to a prior state. 307 type OpenChannel struct { 308 // ChanType denotes which type of channel this is. 309 ChanType ChannelType 310 311 // ChainHash is a hash which represents the blockchain that this 312 // channel will be opened within. This value is typically the genesis 313 // hash. In the case that the original chain went through a contentious 314 // hard-fork, then this value will be tweaked using the unique fork 315 // point on each branch. 316 ChainHash chainhash.Hash 317 318 // FundingOutpoint is the outpoint of the final funding transaction. 319 // This value uniquely and globally identifies the channel within the 320 // target blockchain as specified by the chain hash parameter. 321 FundingOutpoint wire.OutPoint 322 323 // ShortChannelID encodes the exact location in the chain in which the 324 // channel was initially confirmed. This includes: the block height, 325 // transaction index, and the output within the target transaction. 326 ShortChannelID lnwire.ShortChannelID 327 328 // IsPending indicates whether a channel's funding transaction has been 329 // confirmed. 330 IsPending bool 331 332 // IsInitiator is a bool which indicates if we were the original 333 // initiator for the channel. This value may affect how higher levels 334 // negotiate fees, or close the channel. 335 IsInitiator bool 336 337 // FundingBroadcastHeight is the height in which the funding 338 // transaction was broadcast. This value can be used by higher level 339 // sub-systems to determine if a channel is stale and/or should have 340 // been confirmed before a certain height. 341 FundingBroadcastHeight uint32 342 343 // NumConfsRequired is the number of confirmations a channel's funding 344 // transaction must have received in order to be considered available 345 // for normal transactional use. 346 NumConfsRequired uint16 347 348 // ChannelFlags holds the flags that were sent as part of the 349 // open_channel message. 350 ChannelFlags lnwire.FundingFlag 351 352 // IdentityPub is the identity public key of the remote node this 353 // channel has been established with. 354 IdentityPub *secp256k1.PublicKey 355 356 // Capacity is the total capacity of this channel. 357 Capacity dcrutil.Amount 358 359 // TotalMAtomsSent is the total number of milli-atoms we've sent 360 // within this channel. 361 TotalMAtomsSent lnwire.MilliAtom 362 363 // TotalMAtomsReceived is the total number of milli-atoms we've 364 // received within this channel. 365 TotalMAtomsReceived lnwire.MilliAtom 366 367 // LocalChanCfg is the channel configuration for the local node. 368 LocalChanCfg ChannelConfig 369 370 // RemoteChanCfg is the channel configuration for the remote node. 371 RemoteChanCfg ChannelConfig 372 373 // LocalCommitment is the current local commitment state for the local 374 // party. This is stored distinct from the state of the remote party 375 // as there are certain asymmetric parameters which affect the 376 // structure of each commitment. 377 LocalCommitment ChannelCommitment 378 379 // RemoteCommitment is the current remote commitment state for the 380 // remote party. This is stored distinct from the state of the local 381 // party as there are certain asymmetric parameters which affect the 382 // structure of each commitment. 383 RemoteCommitment ChannelCommitment 384 385 // RemoteCurrentRevocation is the current revocation for their 386 // commitment transaction. However, since this the derived public key, 387 // we don't yet have the private key so we aren't yet able to verify 388 // that it's actually in the hash chain. 389 RemoteCurrentRevocation *secp256k1.PublicKey 390 391 // RemoteNextRevocation is the revocation key to be used for the *next* 392 // commitment transaction we create for the local node. Within the 393 // specification, this value is referred to as the 394 // per-commitment-point. 395 RemoteNextRevocation *secp256k1.PublicKey 396 397 // RevocationProducer is used to generate the revocation in such a way 398 // that remote side might store it efficiently and have the ability to 399 // restore the revocation by index if needed. Current implementation of 400 // secret producer is shachain producer. 401 RevocationProducer shachain.Producer 402 403 // RevocationStore is used to efficiently store the revocations for 404 // previous channels states sent to us by remote side. Current 405 // implementation of secret store is shachain store. 406 RevocationStore shachain.Store 407 408 // FundingTxn is the transaction containing this channel's funding 409 // outpoint. Upon restarts, this txn will be rebroadcast if the channel 410 // is found to be pending. 411 // 412 // NOTE: This value will only be populated for single-funder channels 413 // for which we are the initiator. 414 FundingTxn *wire.MsgTx 415 416 // TODO(roasbeef): eww 417 Db *DB 418 419 // TODO(roasbeef): just need to store local and remote HTLC's? 420 421 sync.RWMutex 422 } 423 424 // ShortChanID returns the current ShortChannelID of this channel. 425 func (c *OpenChannel) ShortChanID() lnwire.ShortChannelID { 426 c.RLock() 427 defer c.RUnlock() 428 429 return c.ShortChannelID 430 } 431 432 // HTLC is the on-disk representation of a hash time-locked contract. HTLCs are 433 // contained within ChannelDeltas which encode the current state of the 434 // commitment between state updates. 435 // 436 // TODO(roasbeef): save space by using smaller ints at tail end? 437 type HTLC struct { 438 // Signature is the signature for the second level covenant transaction 439 // for this HTLC. The second level transaction is a timeout tx in the 440 // case that this is an outgoing HTLC, and a success tx in the case 441 // that this is an incoming HTLC. 442 // 443 // TODO(roasbeef): make [64]byte instead? 444 Signature []byte 445 446 // RHash is the payment hash of the HTLC. 447 RHash [32]byte 448 449 // Amt is the amount of milli-satoshis this HTLC escrows. 450 Amt lnwire.MilliAtom 451 452 // RefundTimeout is the absolute timeout on the HTLC that the sender 453 // must wait before reclaiming the funds in limbo. 454 RefundTimeout uint32 455 456 // OutputIndex is the output index for this particular HTLC output 457 // within the commitment transaction. 458 OutputIndex int32 459 460 // Incoming denotes whether we're the receiver or the sender of this 461 // HTLC. 462 Incoming bool 463 464 // OnionBlob is an opaque blob which is used to complete multi-hop 465 // routing. 466 OnionBlob []byte 467 468 // HtlcIndex is the HTLC counter index of this active, outstanding 469 // HTLC. This differs from the LogIndex, as the HtlcIndex is only 470 // incremented for each offered HTLC, while they LogIndex is 471 // incremented for each update (includes settle+fail). 472 HtlcIndex uint64 473 474 // LogIndex is the cumulative log index of this HTLC. This differs 475 // from the HtlcIndex as this will be incremented for each new log 476 // update added. 477 LogIndex uint64 478 } 479 480 // CircuitKey is used by a channel to uniquely identify the HTLCs it receives 481 // from the switch, and is used to purge our in-memory state of HTLCs that have 482 // already been processed by a link. Two list of CircuitKeys are included in 483 // each CommitDiff to allow a link to determine which in-memory htlcs directed 484 // the opening and closing of circuits in the switch's circuit map. 485 type CircuitKey struct { 486 // ChanID is the short chanid indicating the HTLC's origin. 487 // 488 // NOTE: It is fine for this value to be blank, as this indicates a 489 // locally-sourced payment. 490 ChanID lnwire.ShortChannelID 491 492 // HtlcID is the unique htlc index predominately assigned by links, 493 // though can also be assigned by switch in the case of locally-sourced 494 // payments. 495 HtlcID uint64 496 } 497 498 // String returns a string representation of the CircuitKey. 499 func (k CircuitKey) String() string { 500 return fmt.Sprintf("(Chan ID=%s, HTLC ID=%d)", k.ChanID, k.HtlcID) 501 } 502 503 // ClosureType is an enum like structure that details exactly _how_ a channel 504 // was closed. Three closure types are currently possible: none, cooperative, 505 // local force close, remote force close, and (remote) breach. 506 type ClosureType uint8 507 508 const ( 509 // RemoteForceClose indicates that the remote peer has unilaterally 510 // broadcast their current commitment state on-chain. 511 RemoteForceClose ClosureType = 4 512 ) 513 514 // ChannelCloseSummary contains the final state of a channel at the point it 515 // was closed. Once a channel is closed, all the information pertaining to that 516 // channel within the openChannelBucket is deleted, and a compact summary is 517 // put in place instead. 518 type ChannelCloseSummary struct { 519 // ChanPoint is the outpoint for this channel's funding transaction, 520 // and is used as a unique identifier for the channel. 521 ChanPoint wire.OutPoint 522 523 // ShortChanID encodes the exact location in the chain in which the 524 // channel was initially confirmed. This includes: the block height, 525 // transaction index, and the output within the target transaction. 526 ShortChanID lnwire.ShortChannelID 527 528 // ChainHash is the hash of the genesis block that this channel resides 529 // within. 530 ChainHash chainhash.Hash 531 532 // ClosingTXID is the txid of the transaction which ultimately closed 533 // this channel. 534 ClosingTXID chainhash.Hash 535 536 // RemotePub is the public key of the remote peer that we formerly had 537 // a channel with. 538 RemotePub *secp256k1.PublicKey 539 540 // Capacity was the total capacity of the channel. 541 Capacity dcrutil.Amount 542 543 // CloseHeight is the height at which the funding transaction was 544 // spent. 545 CloseHeight uint32 546 547 // SettledBalance is our total balance settled balance at the time of 548 // channel closure. This _does not_ include the sum of any outputs that 549 // have been time-locked as a result of the unilateral channel closure. 550 SettledBalance dcrutil.Amount 551 552 // TimeLockedBalance is the sum of all the time-locked outputs at the 553 // time of channel closure. If we triggered the force closure of this 554 // channel, then this value will be non-zero if our settled output is 555 // above the dust limit. If we were on the receiving side of a channel 556 // force closure, then this value will be non-zero if we had any 557 // outstanding outgoing HTLC's at the time of channel closure. 558 TimeLockedBalance dcrutil.Amount 559 560 // CloseType details exactly _how_ the channel was closed. Five closure 561 // types are possible: cooperative, local force, remote force, breach 562 // and funding canceled. 563 CloseType ClosureType 564 565 // IsPending indicates whether this channel is in the 'pending close' 566 // state, which means the channel closing transaction has been 567 // confirmed, but not yet been fully resolved. In the case of a channel 568 // that has been cooperatively closed, it will go straight into the 569 // fully resolved state as soon as the closing transaction has been 570 // confirmed. However, for channels that have been force closed, they'll 571 // stay marked as "pending" until _all_ the pending funds have been 572 // swept. 573 IsPending bool 574 575 // RemoteCurrentRevocation is the current revocation for their 576 // commitment transaction. However, since this is the derived public key, 577 // we don't yet have the private key so we aren't yet able to verify 578 // that it's actually in the hash chain. 579 RemoteCurrentRevocation *secp256k1.PublicKey 580 581 // RemoteNextRevocation is the revocation key to be used for the *next* 582 // commitment transaction we create for the local node. Within the 583 // specification, this value is referred to as the 584 // per-commitment-point. 585 RemoteNextRevocation *secp256k1.PublicKey 586 587 // LocalChanCfg is the channel configuration for the local node. 588 LocalChanConfig ChannelConfig 589 590 // LastChanSyncMsg is the ChannelReestablish message for this channel 591 // for the state at the point where it was closed. 592 LastChanSyncMsg *lnwire.ChannelReestablish 593 } 594 595 func serializeChannelCloseSummary(w io.Writer, cs *ChannelCloseSummary) error { 596 err := WriteElements(w, 597 cs.ChanPoint, cs.ShortChanID, cs.ChainHash, cs.ClosingTXID, 598 cs.CloseHeight, cs.RemotePub, cs.Capacity, cs.SettledBalance, 599 cs.TimeLockedBalance, cs.CloseType, cs.IsPending, 600 ) 601 if err != nil { 602 return err 603 } 604 605 // If this is a close channel summary created before the addition of 606 // the new fields, then we can exit here. 607 if cs.RemoteCurrentRevocation == nil { 608 return WriteElements(w, false) 609 } 610 611 // If fields are present, write boolean to indicate this, and continue. 612 if err := WriteElements(w, true); err != nil { 613 return err 614 } 615 616 if err := WriteElements(w, cs.RemoteCurrentRevocation); err != nil { 617 return err 618 } 619 620 if err := writeChanConfig(w, &cs.LocalChanConfig); err != nil { 621 return err 622 } 623 624 // The RemoteNextRevocation field is optional, as it's possible for a 625 // channel to be closed before we learn of the next unrevoked 626 // revocation point for the remote party. Write a boolen indicating 627 // whether this field is present or not. 628 if err := WriteElements(w, cs.RemoteNextRevocation != nil); err != nil { 629 return err 630 } 631 632 // Write the field, if present. 633 if cs.RemoteNextRevocation != nil { 634 if err = WriteElements(w, cs.RemoteNextRevocation); err != nil { 635 return err 636 } 637 } 638 639 // Write whether the channel sync message is present. 640 if err := WriteElements(w, cs.LastChanSyncMsg != nil); err != nil { 641 return err 642 } 643 644 // Write the channel sync message, if present. 645 if cs.LastChanSyncMsg != nil { 646 if err := WriteElements(w, cs.LastChanSyncMsg); err != nil { 647 return err 648 } 649 } 650 651 return nil 652 } 653 654 func deserializeCloseChannelSummary(r io.Reader) (*ChannelCloseSummary, error) { 655 c := &ChannelCloseSummary{} 656 657 err := ReadElements(r, 658 &c.ChanPoint, &c.ShortChanID, &c.ChainHash, &c.ClosingTXID, 659 &c.CloseHeight, &c.RemotePub, &c.Capacity, &c.SettledBalance, 660 &c.TimeLockedBalance, &c.CloseType, &c.IsPending, 661 ) 662 if err != nil { 663 return nil, err 664 } 665 666 // We'll now check to see if the channel close summary was encoded with 667 // any of the additional optional fields. 668 var hasNewFields bool 669 err = ReadElements(r, &hasNewFields) 670 if err != nil { 671 return nil, err 672 } 673 674 // If fields are not present, we can return. 675 if !hasNewFields { 676 return c, nil 677 } 678 679 // Otherwise read the new fields. 680 if err := ReadElements(r, &c.RemoteCurrentRevocation); err != nil { 681 return nil, err 682 } 683 684 if err := readChanConfig(r, &c.LocalChanConfig); err != nil { 685 return nil, err 686 } 687 688 // Finally, we'll attempt to read the next unrevoked commitment point 689 // for the remote party. If we closed the channel before receiving a 690 // funding locked message then this might not be present. A boolean 691 // indicating whether the field is present will come first. 692 var hasRemoteNextRevocation bool 693 err = ReadElements(r, &hasRemoteNextRevocation) 694 if err != nil { 695 return nil, err 696 } 697 698 // If this field was written, read it. 699 if hasRemoteNextRevocation { 700 err = ReadElements(r, &c.RemoteNextRevocation) 701 if err != nil { 702 return nil, err 703 } 704 } 705 706 // Check if we have a channel sync message to read. 707 var hasChanSyncMsg bool 708 err = ReadElements(r, &hasChanSyncMsg) 709 if err == io.EOF { 710 return c, nil 711 } else if err != nil { 712 return nil, err 713 } 714 715 // If a chan sync message is present, read it. 716 if hasChanSyncMsg { 717 // We must pass in reference to a lnwire.Message for the codec 718 // to support it. 719 var msg lnwire.Message 720 if err := ReadElements(r, &msg); err != nil { 721 return nil, err 722 } 723 724 chanSync, ok := msg.(*lnwire.ChannelReestablish) 725 if !ok { 726 return nil, errors.New("unable cast db Message to " + 727 "ChannelReestablish") 728 } 729 c.LastChanSyncMsg = chanSync 730 } 731 732 return c, nil 733 } 734 735 func writeChanConfig(b io.Writer, c *ChannelConfig) error { 736 return WriteElements(b, 737 c.DustLimit, c.MaxPendingAmount, c.ChanReserve, c.MinHTLC, 738 c.MaxAcceptedHtlcs, c.CsvDelay, c.MultiSigKey, 739 c.RevocationBasePoint, c.PaymentBasePoint, c.DelayBasePoint, 740 c.HtlcBasePoint, 741 ) 742 } 743 744 func readChanConfig(b io.Reader, c *ChannelConfig) error { 745 return ReadElements(b, 746 &c.DustLimit, &c.MaxPendingAmount, &c.ChanReserve, 747 &c.MinHTLC, &c.MaxAcceptedHtlcs, &c.CsvDelay, 748 &c.MultiSigKey, &c.RevocationBasePoint, 749 &c.PaymentBasePoint, &c.DelayBasePoint, 750 &c.HtlcBasePoint, 751 ) 752 }