github.com/decred/dcrlnd@v0.7.6/lnwallet/reservation.go (about) 1 package lnwallet 2 3 import ( 4 "errors" 5 "net" 6 "sync" 7 8 "github.com/decred/dcrd/chaincfg/chainhash" 9 "github.com/decred/dcrd/dcrec/secp256k1/v4" 10 "github.com/decred/dcrd/dcrutil/v4" 11 "github.com/decred/dcrd/wire" 12 "github.com/decred/dcrlnd/channeldb" 13 "github.com/decred/dcrlnd/input" 14 "github.com/decred/dcrlnd/keychain" 15 "github.com/decred/dcrlnd/lnwallet/chainfee" 16 "github.com/decred/dcrlnd/lnwallet/chanfunding" 17 "github.com/decred/dcrlnd/lnwire" 18 ) 19 20 // CommitmentType is an enum indicating the commitment type we should use for 21 // the channel we are opening. 22 type CommitmentType int 23 24 const ( 25 // CommitmentTypeLegacy is the legacy commitment format with a tweaked 26 // to_remote key. 27 CommitmentTypeLegacy = iota 28 29 // CommitmentTypeTweakless is a newer commitment format where the 30 // to_remote key is static. 31 CommitmentTypeTweakless 32 33 // CommitmentTypeAnchorsZeroFeeHtlcTx is a commitment type that is an 34 // extension of the outdated CommitmentTypeAnchors, which in addition 35 // requires second-level HTLC transactions to be signed using a 36 // zero-fee. 37 CommitmentTypeAnchorsZeroFeeHtlcTx 38 39 // CommitmentTypeScriptEnforcedLease is a commitment type that builds 40 // upon CommitmentTypeTweakless and CommitmentTypeAnchorsZeroFeeHtlcTx, 41 // which in addition requires a CLTV clause to spend outputs paying to 42 // the channel initiator. This is intended for use on leased channels to 43 // guarantee that the channel initiator has no incentives to close a 44 // leased channel before its maturity date. 45 CommitmentTypeScriptEnforcedLease 46 ) 47 48 // HasStaticRemoteKey returns whether the commitment type supports remote 49 // outputs backed by static keys. 50 func (c CommitmentType) HasStaticRemoteKey() bool { 51 switch c { 52 case CommitmentTypeTweakless, 53 CommitmentTypeAnchorsZeroFeeHtlcTx, 54 CommitmentTypeScriptEnforcedLease: 55 return true 56 default: 57 return false 58 } 59 } 60 61 // HasAnchors returns whether the commitment type supports anchor outputs. 62 func (c CommitmentType) HasAnchors() bool { 63 switch c { 64 case CommitmentTypeAnchorsZeroFeeHtlcTx, 65 CommitmentTypeScriptEnforcedLease: 66 return true 67 default: 68 return false 69 } 70 } 71 72 // String returns the name of the CommitmentType. 73 func (c CommitmentType) String() string { 74 switch c { 75 case CommitmentTypeLegacy: 76 return "legacy" 77 case CommitmentTypeTweakless: 78 return "tweakless" 79 case CommitmentTypeAnchorsZeroFeeHtlcTx: 80 return "anchors-zero-fee-second-level" 81 case CommitmentTypeScriptEnforcedLease: 82 return "script-enforced-lease" 83 default: 84 return "invalid" 85 } 86 } 87 88 // ChannelContribution is the primary constituent of the funding workflow 89 // within lnwallet. Each side first exchanges their respective contributions 90 // along with channel specific parameters like the min fee/kB. Once 91 // contributions have been exchanged, each side will then produce signatures 92 // for all their inputs to the funding transactions, and finally a signature 93 // for the other party's version of the commitment transaction. 94 type ChannelContribution struct { 95 // FundingOutpoint is the amount of funds contributed to the funding 96 // transaction. 97 FundingAmount dcrutil.Amount 98 99 // Inputs to the funding transaction. 100 Inputs []*wire.TxIn 101 102 // ChangeOutputs are the Outputs to be used in the case that the total 103 // value of the funding inputs is greater than the total potential 104 // channel capacity. 105 ChangeOutputs []*wire.TxOut 106 107 // FirstCommitmentPoint is the first commitment point that will be used 108 // to create the revocation key in the first commitment transaction we 109 // send to the remote party. 110 FirstCommitmentPoint *secp256k1.PublicKey 111 112 // ChannelConfig is the concrete contribution that this node is 113 // offering to the channel. This includes all the various constraints 114 // such as the min HTLC, and also all the keys which will be used for 115 // the duration of the channel. 116 *channeldb.ChannelConfig 117 118 // UpfrontShutdown is an optional address to which the channel should be 119 // paid out to on cooperative close. 120 UpfrontShutdown lnwire.DeliveryAddress 121 } 122 123 // toChanConfig returns the raw channel configuration generated by a node's 124 // contribution to the channel. 125 func (c *ChannelContribution) toChanConfig() channeldb.ChannelConfig { 126 return *c.ChannelConfig 127 } 128 129 // ChannelReservation represents an intent to open a lightning payment channel 130 // with a counterparty. The funding processes from reservation to channel opening 131 // is a 3-step process. In order to allow for full concurrency during the 132 // reservation workflow, resources consumed by a contribution are "locked" 133 // themselves. This prevents a number of race conditions such as two funding 134 // transactions double-spending the same input. A reservation can also be 135 // canceled, which removes the resources from limbo, allowing another 136 // reservation to claim them. 137 // 138 // The reservation workflow consists of the following three steps: 139 // 1. lnwallet.InitChannelReservation 140 // * One requests the wallet to allocate the necessary resources for a 141 // channel reservation. These resources are put in limbo for the lifetime 142 // of a reservation. 143 // * Once completed the reservation will have the wallet's contribution 144 // accessible via the .OurContribution() method. This contribution 145 // contains the necessary items to allow the remote party to build both 146 // the funding, and commitment transactions. 147 // 2. ChannelReservation.ProcessContribution/ChannelReservation.ProcessSingleContribution 148 // * The counterparty presents their contribution to the payment channel. 149 // This allows us to build the funding, and commitment transactions 150 // ourselves. 151 // * We're now able to sign our inputs to the funding transactions, and 152 // the counterparty's version of the commitment transaction. 153 // * All signatures crafted by us, are now available via .OurSignatures(). 154 // 3. ChannelReservation.CompleteReservation/ChannelReservation.CompleteReservationSingle 155 // * The final step in the workflow. The counterparty presents the 156 // signatures for all their inputs to the funding transaction, as well 157 // as a signature to our version of the commitment transaction. 158 // * We then verify the validity of all signatures before considering the 159 // channel "open". 160 type ChannelReservation struct { 161 // This mutex MUST be held when either reading or modifying any of the 162 // fields below. 163 sync.RWMutex 164 165 // fundingTx is the funding transaction for this pending channel. 166 fundingTx *wire.MsgTx 167 168 // In order of sorted inputs. Sorting is done in accordance 169 // to BIP-69: https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki. 170 ourFundingInputScripts []*input.Script 171 theirFundingInputScripts []*input.Script 172 173 // Our signature for their version of the commitment transaction. 174 ourCommitmentSig input.Signature 175 theirCommitmentSig input.Signature 176 177 ourContribution *ChannelContribution 178 theirContribution *ChannelContribution 179 180 partialState *channeldb.OpenChannel 181 nodeAddr net.Addr 182 183 // The ID of this reservation, used to uniquely track the reservation 184 // throughout its lifetime. 185 reservationID uint64 186 187 // pendingChanID is the pending channel ID for this channel as 188 // identified within the wire protocol. 189 pendingChanID [32]byte 190 191 // pushMAtoms the amount of milli-atoms that should be pushed to the 192 // responder of a single funding channel as part of the initial 193 // commitment state. 194 pushMAtoms lnwire.MilliAtom 195 196 wallet *LightningWallet 197 chanFunder chanfunding.Assembler 198 199 fundingIntent chanfunding.Intent 200 201 // nextRevocationKeyLoc stores the key locator information for this 202 // channel. 203 nextRevocationKeyLoc keychain.KeyLocator 204 } 205 206 // NewChannelReservation creates a new channel reservation. This function is 207 // used only internally by lnwallet. In order to concurrent safety, the 208 // creation of all channel reservations should be carried out via the 209 // lnwallet.InitChannelReservation interface. 210 func NewChannelReservation(capacity, localFundingAmt dcrutil.Amount, 211 commitFeePerKB chainfee.AtomPerKByte, wallet *LightningWallet, 212 id uint64, pushMAtoms lnwire.MilliAtom, chainHash *chainhash.Hash, 213 flags lnwire.FundingFlag, commitType CommitmentType, 214 fundingAssembler chanfunding.Assembler, 215 pendingChanID [32]byte, thawHeight uint32) (*ChannelReservation, error) { 216 217 var ( 218 ourBalance lnwire.MilliAtom 219 theirBalance lnwire.MilliAtom 220 initiator bool 221 ) 222 223 // Based on the channel type, we determine the initial commit size and 224 // fee. 225 commitSize := input.CommitmentTxSize 226 if commitType.HasAnchors() { 227 commitSize = input.CommitmentWithAnchorsTxSize 228 } 229 commitFee := commitFeePerKB.FeeForSize(commitSize) 230 231 localFundingMAtoms := lnwire.NewMAtomsFromAtoms(localFundingAmt) 232 // TODO(halseth): make method take remote funding amount directly 233 // instead of inferring it from capacity and local amt. 234 capacityMAtoms := lnwire.NewMAtomsFromAtoms(capacity) 235 236 // The total fee paid by the initiator will be the commitment fee in 237 // addition to the two anchor outputs. 238 feeMAtoms := lnwire.NewMAtomsFromAtoms(commitFee) 239 if commitType.HasAnchors() { 240 feeMAtoms += 2 * lnwire.NewMAtomsFromAtoms(anchorSize) 241 } 242 243 // Used to cut down on verbosity. 244 defaultDust := wallet.Cfg.DefaultConstraints.DustLimit 245 246 // If we're the responder to a single-funder reservation, then we have 247 // no initial balance in the channel unless the remote party is pushing 248 // some funds to us within the first commitment state. 249 if localFundingAmt == 0 { 250 ourBalance = pushMAtoms 251 theirBalance = capacityMAtoms - feeMAtoms - pushMAtoms 252 initiator = false 253 254 // If the responder doesn't have enough funds to actually pay 255 // the fees, then we'll bail our early. 256 if int64(theirBalance) < 0 { 257 return nil, ErrFunderBalanceDust( 258 int64(commitFee), int64(theirBalance.ToAtoms()), 259 int64(2*defaultDust), 260 ) 261 } 262 } else { 263 // TODO(roasbeef): need to rework fee structure in general and 264 // also when we "unlock" dual funder within the daemon 265 266 if capacity == localFundingAmt { 267 // If we're initiating a single funder workflow, then 268 // we pay all the initial fees within the commitment 269 // transaction. We also deduct our balance by the 270 // amount pushed as part of the initial state. 271 ourBalance = capacityMAtoms - feeMAtoms - pushMAtoms 272 theirBalance = pushMAtoms 273 } else { 274 // Otherwise, this is a dual funder workflow where both 275 // slides split the amount funded and the commitment 276 // fee. 277 ourBalance = localFundingMAtoms - (feeMAtoms / 2) 278 theirBalance = capacityMAtoms - localFundingMAtoms - (feeMAtoms / 2) + pushMAtoms 279 } 280 281 initiator = true 282 283 // If we, the initiator don't have enough funds to actually pay 284 // the fees, then we'll exit with an error. 285 if int64(ourBalance) < 0 { 286 return nil, ErrFunderBalanceDust( 287 int64(commitFee), int64(ourBalance), 288 int64(2*defaultDust), 289 ) 290 } 291 } 292 293 // If we're the initiator and our starting balance within the channel 294 // after we take account of fees is below 2x the dust limit, then we'll 295 // reject this channel creation request. 296 // 297 // TODO(roasbeef): reject if 30% goes to fees? dust channel 298 if initiator && ourBalance.ToAtoms() <= 2*defaultDust { 299 return nil, ErrFunderBalanceDust( 300 int64(commitFee), 301 int64(ourBalance.ToAtoms()), 302 int64(2*defaultDust), 303 ) 304 } 305 306 // Similarly we ensure their balance is reasonable if we are not the 307 // initiator. 308 if !initiator && theirBalance.ToAtoms() <= 2*defaultDust { 309 return nil, ErrFunderBalanceDust( 310 int64(commitFee), 311 int64(theirBalance.ToAtoms()), 312 int64(2*defaultDust), 313 ) 314 } 315 316 // Next we'll set the channel type based on what we can ascertain about 317 // the balances/push amount within the channel. 318 var chanType channeldb.ChannelType 319 320 // If either of the balances are zero at this point, or we have a 321 // non-zero push amt (there's no pushing for dual funder), then this is 322 // a single-funder channel. 323 if ourBalance == 0 || theirBalance == 0 || pushMAtoms != 0 { 324 // Both the tweakless type and the anchor type is tweakless, 325 // hence set the bit. 326 if commitType.HasStaticRemoteKey() { 327 chanType |= channeldb.SingleFunderTweaklessBit 328 } else { 329 chanType |= channeldb.SingleFunderBit 330 } 331 332 switch a := fundingAssembler.(type) { 333 // The first channels of a batch shouldn't publish the batch TX 334 // to avoid problems if some of the funding flows can't be 335 // completed. Only the last channel of a batch should publish. 336 case chanfunding.ConditionalPublishAssembler: 337 if !a.ShouldPublishFundingTx() { 338 chanType |= channeldb.NoFundingTxBit 339 } 340 341 // Normal funding flow, the assembler creates a TX from the 342 // internal wallet. 343 case chanfunding.FundingTxAssembler: 344 // Do nothing, a FundingTxAssembler has the transaction. 345 346 // If this intent isn't one that's able to provide us with a 347 // funding transaction, then we'll set the chanType bit to 348 // signal that we don't have access to one. 349 default: 350 chanType |= channeldb.NoFundingTxBit 351 } 352 353 } else { 354 // Otherwise, this is a dual funder channel, and no side is 355 // technically the "initiator" 356 initiator = false 357 chanType |= channeldb.DualFunderBit 358 } 359 360 // We are adding anchor outputs to our commitment. We only support this 361 // in combination with zero-fee second-levels HTLCs. 362 if commitType.HasAnchors() { 363 chanType |= channeldb.AnchorOutputsBit 364 chanType |= channeldb.ZeroHtlcTxFeeBit 365 } 366 367 // Set the appropriate LeaseExpiration/Frozen bit based on the 368 // reservation parameters. 369 if commitType == CommitmentTypeScriptEnforcedLease { 370 if thawHeight == 0 { 371 return nil, errors.New("missing absolute expiration " + 372 "for script enforced lease commitment type") 373 } 374 chanType |= channeldb.LeaseExpirationBit 375 } else if thawHeight > 0 { 376 chanType |= channeldb.FrozenBit 377 } 378 379 return &ChannelReservation{ 380 ourContribution: &ChannelContribution{ 381 FundingAmount: ourBalance.ToAtoms(), 382 ChannelConfig: &channeldb.ChannelConfig{}, 383 }, 384 theirContribution: &ChannelContribution{ 385 FundingAmount: theirBalance.ToAtoms(), 386 ChannelConfig: &channeldb.ChannelConfig{}, 387 }, 388 partialState: &channeldb.OpenChannel{ 389 ChanType: chanType, 390 ChainHash: *chainHash, 391 IsPending: true, 392 IsInitiator: initiator, 393 ChannelFlags: flags, 394 Capacity: capacity, 395 LocalCommitment: channeldb.ChannelCommitment{ 396 LocalBalance: ourBalance, 397 RemoteBalance: theirBalance, 398 FeePerKB: dcrutil.Amount(commitFeePerKB), 399 CommitFee: commitFee, 400 }, 401 RemoteCommitment: channeldb.ChannelCommitment{ 402 LocalBalance: ourBalance, 403 RemoteBalance: theirBalance, 404 FeePerKB: dcrutil.Amount(commitFeePerKB), 405 CommitFee: commitFee, 406 }, 407 ThawHeight: thawHeight, 408 Db: wallet.Cfg.Database, 409 }, 410 pushMAtoms: pushMAtoms, 411 pendingChanID: pendingChanID, 412 reservationID: id, 413 wallet: wallet, 414 chanFunder: fundingAssembler, 415 }, nil 416 } 417 418 // SetNumConfsRequired sets the number of confirmations that are required for 419 // the ultimate funding transaction before the channel can be considered open. 420 // This is distinct from the main reservation workflow as it allows 421 // implementations a bit more flexibility w.r.t to if the responder of the 422 // initiator sets decides the number of confirmations needed. 423 func (r *ChannelReservation) SetNumConfsRequired(numConfs uint16) { 424 r.Lock() 425 defer r.Unlock() 426 427 r.partialState.NumConfsRequired = numConfs 428 } 429 430 // CommitConstraints takes the constraints that the remote party specifies for 431 // the type of commitments that we can generate for them. These constraints 432 // include several parameters that serve as flow control restricting the amount 433 // of atoms that can be transferred in a single commitment. This function 434 // will also attempt to verify the constraints for sanity, returning an error 435 // if the parameters are seemed unsound. 436 func (r *ChannelReservation) CommitConstraints(c *channeldb.ChannelConstraints, 437 maxLocalCSVDelay uint16, responder bool) error { 438 r.Lock() 439 defer r.Unlock() 440 441 // Fail if the csv delay for our funds exceeds our maximum. 442 if c.CsvDelay > maxLocalCSVDelay { 443 return ErrCsvDelayTooLarge(c.CsvDelay, maxLocalCSVDelay) 444 } 445 446 // The channel reserve should always be greater or equal to the dust 447 // limit. The reservation request should be denied if otherwise. 448 if c.DustLimit > c.ChanReserve { 449 return ErrChanReserveTooSmall(c.ChanReserve, c.DustLimit) 450 } 451 452 // Validate against the maximum-sized pk script dust limit, and 453 // also ensure that the DustLimit is not too large. 454 maxWitnessLimit := DustLimitForSize(input.P2PKHPkScriptSize) 455 if c.DustLimit < maxWitnessLimit || c.DustLimit > 3*maxWitnessLimit { 456 return ErrInvalidDustLimit(c.DustLimit) 457 } 458 459 // Fail if we consider the channel reserve to be too large. We 460 // currently fail if it is greater than 20% of the channel capacity. 461 maxChanReserve := r.partialState.Capacity / 5 462 if c.ChanReserve > maxChanReserve { 463 return ErrChanReserveTooLarge(c.ChanReserve, maxChanReserve) 464 } 465 466 // Fail if the minimum HTLC value is too large. If this is too large, 467 // the channel won't be useful for sending small payments. This limit 468 // is currently set to maxValueInFlight, effectively letting the remote 469 // setting this as large as it wants. 470 if c.MinHTLC > c.MaxPendingAmount { 471 return ErrMinHtlcTooLarge(c.MinHTLC, c.MaxPendingAmount) 472 } 473 474 // Fail if maxHtlcs is above the maximum allowed number of 483. This 475 // number is specified in BOLT-02. 476 // 477 // FIXME(decred): The MaxHTLCNumber was 322 in previous vesions and was 478 // reduced to 300 recently. We add a special case so that we can still 479 // open channels to old nodes. This should be removed on the next 480 // version. 481 if c.MaxAcceptedHtlcs > uint16(input.MaxHTLCNumber/2) && c.MaxAcceptedHtlcs != 161 { 482 return ErrMaxHtlcNumTooLarge( 483 c.MaxAcceptedHtlcs, uint16(input.MaxHTLCNumber/2), 484 ) 485 } 486 487 // Fail if we consider maxHtlcs too small. If this is too small we 488 // cannot offer many HTLCs to the remote. 489 const minNumHtlc = 5 490 if c.MaxAcceptedHtlcs < minNumHtlc { 491 return ErrMaxHtlcNumTooSmall(c.MaxAcceptedHtlcs, minNumHtlc) 492 } 493 494 // Fail if we consider maxValueInFlight too small. We currently require 495 // the remote to at least allow minNumHtlc * minHtlc in flight. 496 if c.MaxPendingAmount < minNumHtlc*c.MinHTLC { 497 return ErrMaxValueInFlightTooSmall( 498 c.MaxPendingAmount, minNumHtlc*c.MinHTLC, 499 ) 500 } 501 502 // Our dust limit should always be less than or equal to our proposed 503 // channel reserve. 504 if responder && r.ourContribution.DustLimit > c.ChanReserve { 505 r.ourContribution.DustLimit = c.ChanReserve 506 } 507 508 r.ourContribution.ChanReserve = c.ChanReserve 509 r.ourContribution.MaxPendingAmount = c.MaxPendingAmount 510 r.ourContribution.MinHTLC = c.MinHTLC 511 r.ourContribution.MaxAcceptedHtlcs = c.MaxAcceptedHtlcs 512 r.ourContribution.CsvDelay = c.CsvDelay 513 514 return nil 515 } 516 517 // validateReserveBounds checks that both ChannelReserve values are above both 518 // DustLimit values. This not only avoids stuck channels, but is also mandated 519 // by BOLT#02 even if it's not explicit. This returns true if the bounds are 520 // valid. This function should be called with the lock held. 521 func (r *ChannelReservation) validateReserveBounds() bool { 522 ourDustLimit := r.ourContribution.DustLimit 523 ourRequiredReserve := r.ourContribution.ChanReserve 524 theirDustLimit := r.theirContribution.DustLimit 525 theirRequiredReserve := r.theirContribution.ChanReserve 526 527 // We take the smaller of the two ChannelReserves and compare it 528 // against the larger of the two DustLimits. 529 minChanReserve := ourRequiredReserve 530 if minChanReserve > theirRequiredReserve { 531 minChanReserve = theirRequiredReserve 532 } 533 534 maxDustLimit := ourDustLimit 535 if maxDustLimit < theirDustLimit { 536 maxDustLimit = theirDustLimit 537 } 538 539 return minChanReserve >= maxDustLimit 540 } 541 542 // OurContribution returns the wallet's fully populated contribution to the 543 // pending payment channel. See 'ChannelContribution' for further details 544 // regarding the contents of a contribution. 545 // 546 // NOTE: This SHOULD NOT be modified. 547 // TODO(roasbeef): make copy? 548 func (r *ChannelReservation) OurContribution() *ChannelContribution { 549 r.RLock() 550 defer r.RUnlock() 551 552 return r.ourContribution 553 } 554 555 // ProcessContribution verifies the counterparty's contribution to the pending 556 // payment channel. As a result of this incoming message, lnwallet is able to 557 // build the funding transaction, and both commitment transactions. Once this 558 // message has been processed, all signatures to inputs to the funding 559 // transaction belonging to the wallet are available. Additionally, the wallet 560 // will generate a signature to the counterparty's version of the commitment 561 // transaction. 562 func (r *ChannelReservation) ProcessContribution(theirContribution *ChannelContribution) error { 563 errChan := make(chan error, 1) 564 565 r.wallet.msgChan <- &addContributionMsg{ 566 pendingFundingID: r.reservationID, 567 contribution: theirContribution, 568 err: errChan, 569 } 570 571 return <-errChan 572 } 573 574 // IsPsbt returns true if there is a PSBT funding intent mapped to this 575 // reservation. 576 func (r *ChannelReservation) IsPsbt() bool { 577 _, ok := r.fundingIntent.(*chanfunding.PsbtIntent) 578 return ok 579 } 580 581 // IsCannedShim returns true if there is a canned shim funding intent mapped to 582 // this reservation. 583 func (r *ChannelReservation) IsCannedShim() bool { 584 _, ok := r.fundingIntent.(*chanfunding.ShimIntent) 585 return ok 586 } 587 588 // ProcessPsbt continues a previously paused funding flow that involves PSBT to 589 // construct the funding transaction. This method can be called once the PSBT is 590 // finalized and the signed transaction is available. 591 func (r *ChannelReservation) ProcessPsbt() error { 592 errChan := make(chan error, 1) 593 594 r.wallet.msgChan <- &continueContributionMsg{ 595 pendingFundingID: r.reservationID, 596 err: errChan, 597 } 598 599 return <-errChan 600 } 601 602 // RemoteCanceled informs the PSBT funding state machine that the remote peer 603 // has canceled the pending reservation, likely due to a timeout. 604 func (r *ChannelReservation) RemoteCanceled() { 605 psbtIntent, ok := r.fundingIntent.(*chanfunding.PsbtIntent) 606 if !ok { 607 return 608 } 609 psbtIntent.RemoteCanceled() 610 } 611 612 // ProcessSingleContribution verifies, and records the initiator's contribution 613 // to this pending single funder channel. Internally, no further action is 614 // taken other than recording the initiator's contribution to the single funder 615 // channel. 616 func (r *ChannelReservation) ProcessSingleContribution(theirContribution *ChannelContribution) error { 617 errChan := make(chan error, 1) 618 619 r.wallet.msgChan <- &addSingleContributionMsg{ 620 pendingFundingID: r.reservationID, 621 contribution: theirContribution, 622 err: errChan, 623 } 624 625 return <-errChan 626 } 627 628 // TheirContribution returns the counterparty's pending contribution to the 629 // payment channel. See 'ChannelContribution' for further details regarding the 630 // contents of a contribution. This attribute will ONLY be available after a 631 // call to .ProcessContribution(). 632 // 633 // NOTE: This SHOULD NOT be modified. 634 func (r *ChannelReservation) TheirContribution() *ChannelContribution { 635 r.RLock() 636 defer r.RUnlock() 637 return r.theirContribution 638 } 639 640 // OurSignatures retrieves the wallet's signatures to all inputs to the funding 641 // transaction belonging to itself, and also a signature for the counterparty's 642 // version of the commitment transaction. The signatures for the wallet's 643 // inputs to the funding transaction are returned in sorted order according to 644 // BIP-69: https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki. 645 // 646 // NOTE: These signatures will only be populated after a call to 647 // .ProcessContribution() 648 func (r *ChannelReservation) OurSignatures() ([]*input.Script, 649 input.Signature) { 650 651 r.RLock() 652 defer r.RUnlock() 653 return r.ourFundingInputScripts, r.ourCommitmentSig 654 } 655 656 // CompleteReservation finalizes the pending channel reservation, transitioning 657 // from a pending payment channel, to an open payment channel. All passed 658 // signatures to the counterparty's inputs to the funding transaction will be 659 // fully verified. Signatures are expected to be passed in sorted order 660 // according to BIP-69: 661 // https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki. 662 // Additionally, verification is performed in order to ensure that the 663 // counterparty supplied a valid signature to our version of the commitment 664 // transaction. Once this method returns, callers should broadcast the 665 // created funding transaction, then call .WaitForChannelOpen() which will 666 // block until the funding transaction obtains the configured number of 667 // confirmations. Once the method unblocks, a LightningChannel instance is 668 // returned, marking the channel available for updates. 669 func (r *ChannelReservation) CompleteReservation(fundingInputScripts []*input.Script, 670 commitmentSig input.Signature) (*channeldb.OpenChannel, error) { 671 672 // TODO(roasbeef): add flag for watch or not? 673 errChan := make(chan error, 1) 674 completeChan := make(chan *channeldb.OpenChannel, 1) 675 676 r.wallet.msgChan <- &addCounterPartySigsMsg{ 677 pendingFundingID: r.reservationID, 678 theirFundingInputScripts: fundingInputScripts, 679 theirCommitmentSig: commitmentSig, 680 completeChan: completeChan, 681 err: errChan, 682 } 683 684 return <-completeChan, <-errChan 685 } 686 687 // CompleteReservationSingle finalizes the pending single funder channel 688 // reservation. Using the funding outpoint of the constructed funding 689 // transaction, and the initiator's signature for our version of the commitment 690 // transaction, we are able to verify the correctness of our commitment 691 // transaction as crafted by the initiator. Once this method returns, our 692 // signature for the initiator's version of the commitment transaction is 693 // available via the .OurSignatures() method. As this method should only be 694 // called as a response to a single funder channel, only a commitment signature 695 // will be populated. 696 func (r *ChannelReservation) CompleteReservationSingle(fundingPoint *wire.OutPoint, 697 commitSig input.Signature) (*channeldb.OpenChannel, error) { 698 699 errChan := make(chan error, 1) 700 completeChan := make(chan *channeldb.OpenChannel, 1) 701 702 r.wallet.msgChan <- &addSingleFunderSigsMsg{ 703 pendingFundingID: r.reservationID, 704 fundingOutpoint: fundingPoint, 705 theirCommitmentSig: commitSig, 706 completeChan: completeChan, 707 err: errChan, 708 } 709 710 return <-completeChan, <-errChan 711 } 712 713 // TheirSignatures returns the counterparty's signatures to all inputs to the 714 // funding transaction belonging to them, as well as their signature for the 715 // wallet's version of the commitment transaction. This methods is provided for 716 // additional verification, such as needed by tests. 717 // 718 // NOTE: These attributes will be unpopulated before a call to 719 // .CompleteReservation(). 720 func (r *ChannelReservation) TheirSignatures() ([]*input.Script, 721 input.Signature) { 722 723 r.RLock() 724 defer r.RUnlock() 725 return r.theirFundingInputScripts, r.theirCommitmentSig 726 } 727 728 // FinalFundingTx returns the finalized, fully signed funding transaction for 729 // this reservation. 730 // 731 // NOTE: If this reservation was created as the non-initiator to a single 732 // funding workflow, then the full funding transaction will not be available. 733 // Instead we will only have the final outpoint of the funding transaction. 734 func (r *ChannelReservation) FinalFundingTx() *wire.MsgTx { 735 r.RLock() 736 defer r.RUnlock() 737 return r.fundingTx 738 } 739 740 // FundingOutpoint returns the outpoint of the funding transaction. 741 // 742 // NOTE: The pointer returned will only be set once the .ProcessContribution() 743 // method is called in the case of the initiator of a single funder workflow, 744 // and after the .CompleteReservationSingle() method is called in the case of 745 // a responder to a single funder workflow. 746 func (r *ChannelReservation) FundingOutpoint() *wire.OutPoint { 747 r.RLock() 748 defer r.RUnlock() 749 return &r.partialState.FundingOutpoint 750 } 751 752 // SetOurUpfrontShutdown sets the upfront shutdown address on our contribution. 753 func (r *ChannelReservation) SetOurUpfrontShutdown(shutdown lnwire.DeliveryAddress) { 754 r.Lock() 755 defer r.Unlock() 756 757 r.ourContribution.UpfrontShutdown = shutdown 758 } 759 760 // Capacity returns the channel capacity for this reservation. 761 func (r *ChannelReservation) Capacity() dcrutil.Amount { 762 r.RLock() 763 defer r.RUnlock() 764 return r.partialState.Capacity 765 } 766 767 // LeaseExpiry returns the absolute expiration height for a leased channel using 768 // the script enforced commitment type. A zero value is returned when the 769 // channel is not using a script enforced lease commitment type. 770 func (r *ChannelReservation) LeaseExpiry() uint32 { 771 if !r.partialState.ChanType.HasLeaseExpiration() { 772 return 0 773 } 774 return r.partialState.ThawHeight 775 } 776 777 // Cancel abandons this channel reservation. This method should be called in 778 // the scenario that communications with the counterparty break down. Upon 779 // cancellation, all resources previously reserved for this pending payment 780 // channel are returned to the free pool, allowing subsequent reservations to 781 // utilize the now freed resources. 782 func (r *ChannelReservation) Cancel() error { 783 errChan := make(chan error, 1) 784 r.wallet.msgChan <- &fundingReserveCancelMsg{ 785 pendingFundingID: r.reservationID, 786 err: errChan, 787 } 788 789 return <-errChan 790 } 791 792 // OpenChannelDetails wraps the finalized fully confirmed channel which 793 // resulted from a ChannelReservation instance with details concerning exactly 794 // _where_ in the chain the channel was ultimately opened. 795 type OpenChannelDetails struct { 796 // Channel is the active channel created by an instance of a 797 // ChannelReservation and the required funding workflow. 798 Channel *LightningChannel 799 800 // ConfirmationHeight is the block height within the chain that 801 // included the channel. 802 ConfirmationHeight uint32 803 804 // TransactionIndex is the index within the confirming block that the 805 // transaction resides. 806 TransactionIndex uint32 807 }