github.com/decred/dcrlnd@v0.7.6/lnwallet/commitment.go (about) 1 package lnwallet 2 3 import ( 4 "fmt" 5 6 "github.com/decred/dcrd/blockchain/standalone/v2" 7 "github.com/decred/dcrd/chaincfg/v3" 8 "github.com/decred/dcrd/dcrec/secp256k1/v4" 9 "github.com/decred/dcrd/dcrutil/v4" 10 "github.com/decred/dcrd/txscript/v4" 11 "github.com/decred/dcrd/wire" 12 "github.com/decred/dcrlnd/channeldb" 13 "github.com/decred/dcrlnd/input" 14 "github.com/decred/dcrlnd/lnwallet/chainfee" 15 "github.com/decred/dcrlnd/lnwire" 16 ) 17 18 // anchorSize is the constant anchor output size. 19 // 20 // TODO(decred) figure out the best value for this. Currently 2*dust. 21 const anchorSize = dcrutil.Amount(12060) 22 23 // DefaultAnchorsCommitMaxFeeRateAtomsPerByte is the default max fee rate in 24 // atoms/byte the initiator will use for anchor channels. This should be enough 25 // to ensure propagation before anchoring down the commitment transaction. 26 const DefaultAnchorsCommitMaxFeeRateAtomsPerByte = 10 27 28 // CommitmentKeyRing holds all derived keys needed to construct commitment and 29 // HTLC transactions. The keys are derived differently depending whether the 30 // commitment transaction is ours or the remote peer's. Private keys associated 31 // with each key may belong to the commitment owner or the "other party" which 32 // is referred to in the field comments, regardless of which is local and which 33 // is remote. 34 type CommitmentKeyRing struct { 35 // CommitPoint is the "per commitment point" used to derive the tweak 36 // for each base point. 37 CommitPoint *secp256k1.PublicKey 38 39 // LocalCommitKeyTweak is the tweak used to derive the local public key 40 // from the local payment base point or the local private key from the 41 // base point secret. This may be included in a SignDescriptor to 42 // generate signatures for the local payment key. 43 // 44 // NOTE: This will always refer to "our" local key, regardless of 45 // whether this is our commit or not. 46 LocalCommitKeyTweak []byte 47 48 // TODO(roasbeef): need delay tweak as well? 49 50 // LocalHtlcKeyTweak is the tweak used to derive the local HTLC key 51 // from the local HTLC base point. This value is needed in order to 52 // derive the final key used within the HTLC scripts in the commitment 53 // transaction. 54 // 55 // NOTE: This will always refer to "our" local HTLC key, regardless of 56 // whether this is our commit or not. 57 LocalHtlcKeyTweak []byte 58 59 // LocalHtlcKey is the key that will be used in any clause paying to 60 // our node of any HTLC scripts within the commitment transaction for 61 // this key ring set. 62 // 63 // NOTE: This will always refer to "our" local HTLC key, regardless of 64 // whether this is our commit or not. 65 LocalHtlcKey *secp256k1.PublicKey 66 67 // RemoteHtlcKey is the key that will be used in clauses within the 68 // HTLC script that send money to the remote party. 69 // 70 // NOTE: This will always refer to "their" remote HTLC key, regardless 71 // of whether this is our commit or not. 72 RemoteHtlcKey *secp256k1.PublicKey 73 74 // ToLocalKey is the commitment transaction owner's key which is 75 // included in HTLC success and timeout transaction scripts. This is 76 // the public key used for the to_local output of the commitment 77 // transaction. 78 // 79 // NOTE: Who's key this is depends on the current perspective. If this 80 // is our commitment this will be our key. 81 ToLocalKey *secp256k1.PublicKey 82 83 // ToRemoteKey is the non-owner's payment key in the commitment tx. 84 // This is the key used to generate the to_remote output within the 85 // commitment transaction. 86 // 87 // NOTE: Who's key this is depends on the current perspective. If this 88 // is our commitment this will be their key. 89 ToRemoteKey *secp256k1.PublicKey 90 91 // RevocationKey is the key that can be used by the other party to 92 // redeem outputs from a revoked commitment transaction if it were to 93 // be published. 94 // 95 // NOTE: Who can sign for this key depends on the current perspective. 96 // If this is our commitment, it means the remote node can sign for 97 // this key in case of a breach. 98 RevocationKey *secp256k1.PublicKey 99 } 100 101 // DeriveCommitmentKeys generates a new commitment key set using the base 102 // points and commitment point. The keys are derived differently depending on 103 // the type of channel, and whether the commitment transaction is ours or the 104 // remote peer's. 105 func DeriveCommitmentKeys(commitPoint *secp256k1.PublicKey, 106 isOurCommit bool, chanType channeldb.ChannelType, 107 localChanCfg, remoteChanCfg *channeldb.ChannelConfig) *CommitmentKeyRing { 108 109 tweaklessCommit := chanType.IsTweakless() 110 111 // Depending on if this is our commit or not, we'll choose the correct 112 // base point. 113 localBasePoint := localChanCfg.PaymentBasePoint 114 if isOurCommit { 115 localBasePoint = localChanCfg.DelayBasePoint 116 } 117 118 // First, we'll derive all the keys that don't depend on the context of 119 // whose commitment transaction this is. 120 keyRing := &CommitmentKeyRing{ 121 CommitPoint: commitPoint, 122 123 LocalCommitKeyTweak: input.SingleTweakBytes( 124 commitPoint, localBasePoint.PubKey, 125 ), 126 LocalHtlcKeyTweak: input.SingleTweakBytes( 127 commitPoint, localChanCfg.HtlcBasePoint.PubKey, 128 ), 129 LocalHtlcKey: input.TweakPubKey( 130 localChanCfg.HtlcBasePoint.PubKey, commitPoint, 131 ), 132 RemoteHtlcKey: input.TweakPubKey( 133 remoteChanCfg.HtlcBasePoint.PubKey, commitPoint, 134 ), 135 } 136 137 // We'll now compute the to_local, to_remote, and revocation key based 138 // on the current commitment point. All keys are tweaked each state in 139 // order to ensure the keys from each state are unlinkable. To create 140 // the revocation key, we take the opposite party's revocation base 141 // point and combine that with the current commitment point. 142 var ( 143 toLocalBasePoint *secp256k1.PublicKey 144 toRemoteBasePoint *secp256k1.PublicKey 145 revocationBasePoint *secp256k1.PublicKey 146 ) 147 if isOurCommit { 148 toLocalBasePoint = localChanCfg.DelayBasePoint.PubKey 149 toRemoteBasePoint = remoteChanCfg.PaymentBasePoint.PubKey 150 revocationBasePoint = remoteChanCfg.RevocationBasePoint.PubKey 151 } else { 152 toLocalBasePoint = remoteChanCfg.DelayBasePoint.PubKey 153 toRemoteBasePoint = localChanCfg.PaymentBasePoint.PubKey 154 revocationBasePoint = localChanCfg.RevocationBasePoint.PubKey 155 } 156 157 // With the base points assigned, we can now derive the actual keys 158 // using the base point, and the current commitment tweak. 159 keyRing.ToLocalKey = input.TweakPubKey(toLocalBasePoint, commitPoint) 160 keyRing.RevocationKey = input.DeriveRevocationPubkey( 161 revocationBasePoint, commitPoint, 162 ) 163 164 // If this commitment should omit the tweak for the remote point, then 165 // we'll use that directly, and ignore the commitPoint tweak. 166 if tweaklessCommit { 167 keyRing.ToRemoteKey = toRemoteBasePoint 168 169 // If this is not our commitment, the above ToRemoteKey will be 170 // ours, and we blank out the local commitment tweak to 171 // indicate that the key should not be tweaked when signing. 172 if !isOurCommit { 173 keyRing.LocalCommitKeyTweak = nil 174 } 175 } else { 176 keyRing.ToRemoteKey = input.TweakPubKey( 177 toRemoteBasePoint, commitPoint, 178 ) 179 } 180 181 return keyRing 182 } 183 184 // ScriptInfo holds a redeem script and hash. 185 type ScriptInfo struct { 186 // PkScript is the output's PkScript. 187 PkScript []byte 188 189 // WitnessScript is the full script required to properly redeem the 190 // output. This field should be set to the full script if a p2wsh 191 // output is being signed. For p2wkh it should be set equal to the 192 // PkScript. 193 WitnessScript []byte 194 } 195 196 // CommitScriptToSelf constructs the public key script for the output on the 197 // commitment transaction paying to the "owner" of said commitment transaction. 198 // The `initiator` argument should correspond to the owner of the commitment 199 // tranasction which we are generating the to_local script for. If the other 200 // party learns of the preimage to the revocation hash, then they can claim all 201 // the settled funds in the channel, plus the unsettled funds. 202 func CommitScriptToSelf(chanType channeldb.ChannelType, initiator bool, 203 selfKey, revokeKey *secp256k1.PublicKey, csvDelay, leaseExpiry uint32) ( 204 *ScriptInfo, error) { 205 206 var ( 207 toLocalRedeemScript []byte 208 err error 209 ) 210 switch { 211 // If we are the initiator of a leased channel, then we have an 212 // additional CLTV requirement in addition to the usual CSV requirement. 213 case initiator && chanType.HasLeaseExpiration(): 214 toLocalRedeemScript, err = input.LeaseCommitScriptToSelf( 215 selfKey, revokeKey, csvDelay, leaseExpiry, 216 ) 217 218 default: 219 toLocalRedeemScript, err = input.CommitScriptToSelf( 220 csvDelay, selfKey, revokeKey, 221 ) 222 } 223 if err != nil { 224 return nil, err 225 } 226 227 toLocalScriptHash, err := input.ScriptHashPkScript(toLocalRedeemScript) 228 if err != nil { 229 return nil, err 230 } 231 232 return &ScriptInfo{ 233 PkScript: toLocalScriptHash, 234 WitnessScript: toLocalRedeemScript, 235 }, nil 236 } 237 238 // CommitScriptToRemote derives the appropriate to_remote script based on the 239 // channel's commitment type. The `initiator` argument should correspond to the 240 // owner of the commitment tranasction which we are generating the to_remote 241 // script for. The second return value is the CSV delay of the output script, 242 // what must be satisfied in order to spend the output. 243 func CommitScriptToRemote(chanType channeldb.ChannelType, initiator bool, 244 key *secp256k1.PublicKey, leaseExpiry uint32) (*ScriptInfo, uint32, error) { 245 246 switch { 247 // If we are not the initiator of a leased channel, then the remote 248 // party has an additional CLTV requirement in addition to the 1 block 249 // CSV requirement. 250 case chanType.HasLeaseExpiration() && !initiator: 251 script, err := input.LeaseCommitScriptToRemoteConfirmed( 252 key, leaseExpiry, 253 ) 254 if err != nil { 255 return nil, 0, err 256 } 257 258 p2sh, err := input.ScriptHashPkScript(script) 259 if err != nil { 260 return nil, 0, err 261 } 262 263 return &ScriptInfo{ 264 PkScript: p2sh, 265 WitnessScript: script, 266 }, 1, nil 267 268 // If this channel type has anchors, we derive the delayed to_remote 269 // script. 270 case chanType.HasAnchors(): 271 script, err := input.CommitScriptToRemoteConfirmed(key) 272 if err != nil { 273 return nil, 0, err 274 } 275 276 p2sh, err := input.ScriptHashPkScript(script) 277 if err != nil { 278 return nil, 0, err 279 } 280 281 return &ScriptInfo{ 282 PkScript: p2sh, 283 WitnessScript: script, 284 }, 1, nil 285 286 default: 287 // Otherwise the to_remote will be a simple p2pkh. 288 p2pkh, err := input.CommitScriptUnencumbered(key) 289 if err != nil { 290 return nil, 0, err 291 } 292 293 // Since this is a regular P2PKH, the WitnessScipt and PkScript 294 // should both be set to the script hash. 295 return &ScriptInfo{ 296 WitnessScript: p2pkh, 297 PkScript: p2pkh, 298 }, 0, nil 299 300 } 301 } 302 303 // HtlcSigHashType returns the sighash type to use for HTLC success and timeout 304 // transactions given the channel type. 305 func HtlcSigHashType(chanType channeldb.ChannelType) txscript.SigHashType { 306 if chanType.HasAnchors() { 307 return txscript.SigHashSingle | txscript.SigHashAnyOneCanPay 308 } 309 310 return txscript.SigHashAll 311 } 312 313 // HtlcSignDetails converts the passed parameters to a SignDetails valid for 314 // this channel type. For non-anchor channels this will return nil. 315 func HtlcSignDetails(chanType channeldb.ChannelType, signDesc input.SignDescriptor, 316 sigHash txscript.SigHashType, peerSig input.Signature) *input.SignDetails { 317 318 // Non-anchor channels don't need sign details, as the HTLC second 319 // level cannot be altered. 320 if !chanType.HasAnchors() { 321 return nil 322 } 323 324 return &input.SignDetails{ 325 SignDesc: signDesc, 326 SigHashType: sigHash, 327 PeerSig: peerSig, 328 } 329 } 330 331 // HtlcSecondLevelInputSequence dictates the sequence number we must use on the 332 // input to a second level HTLC transaction. 333 func HtlcSecondLevelInputSequence(chanType channeldb.ChannelType) uint32 { 334 if chanType.HasAnchors() { 335 return 1 336 } 337 338 return 0 339 } 340 341 // SecondLevelHtlcScript derives the appropriate second level HTLC script based 342 // on the channel's commitment type. It is the uniform script that's used as the 343 // output for the second-level HTLC transactions. The second level transaction 344 // act as a sort of covenant, ensuring that a 2-of-2 multi-sig output can only 345 // be spent in a particular way, and to a particular output. The `initiator` 346 // argument should correspond to the owner of the commitment tranasction which 347 // we are generating the to_local script for. 348 func SecondLevelHtlcScript(chanType channeldb.ChannelType, initiator bool, 349 revocationKey, delayKey *secp256k1.PublicKey, 350 csvDelay, leaseExpiry uint32) (*ScriptInfo, error) { 351 352 var ( 353 redeemScript []byte 354 err error 355 ) 356 switch { 357 // If we are the initiator of a leased channel, then we have an 358 // additional CLTV requirement in addition to the usual CSV requirement. 359 case initiator && chanType.HasLeaseExpiration(): 360 redeemScript, err = input.LeaseSecondLevelHtlcScript( 361 revocationKey, delayKey, csvDelay, leaseExpiry, 362 ) 363 364 default: 365 redeemScript, err = input.SecondLevelHtlcScript( 366 revocationKey, delayKey, csvDelay, 367 ) 368 } 369 if err != nil { 370 return nil, err 371 } 372 373 pkScript, err := input.ScriptHashPkScript(redeemScript) 374 if err != nil { 375 return nil, err 376 } 377 378 return &ScriptInfo{ 379 PkScript: pkScript, 380 WitnessScript: redeemScript, 381 }, nil 382 } 383 384 // CommitSize returns the base commitment size before adding HTLCs. 385 func CommitSize(chanType channeldb.ChannelType) int64 { 386 // If this commitment has anchors, it will be slightly heavier. 387 if chanType.HasAnchors() { 388 return input.CommitmentWithAnchorsTxSize 389 } 390 391 return input.CommitmentTxSize 392 } 393 394 // HtlcTimeoutFee returns the fee in satoshis required for an HTLC timeout 395 // transaction based on the current fee rate. 396 func HtlcTimeoutFee(chanType channeldb.ChannelType, 397 feePerKB chainfee.AtomPerKByte) dcrutil.Amount { 398 399 // For zero-fee HTLC channels, this will always be zero, regardless of 400 // feerate. 401 if chanType.ZeroHtlcTxFee() { 402 return 0 403 } 404 405 if chanType.HasAnchors() { 406 return feePerKB.FeeForSize(input.HTLCTimeoutConfirmedTxSize) 407 } 408 409 return feePerKB.FeeForSize(input.HTLCTimeoutTxSize) 410 } 411 412 // HtlcSuccessFee returns the fee in satoshis required for an HTLC success 413 // transaction based on the current fee rate. 414 func HtlcSuccessFee(chanType channeldb.ChannelType, 415 feePerKB chainfee.AtomPerKByte) dcrutil.Amount { 416 417 // For zero-fee HTLC channels, this will always be zero, regardless of 418 // feerate. 419 if chanType.ZeroHtlcTxFee() { 420 return 0 421 } 422 423 if chanType.HasAnchors() { 424 return feePerKB.FeeForSize(input.HTLCSuccessConfirmedTxSize) 425 } 426 return feePerKB.FeeForSize(input.HTLCSuccessTxSize) 427 } 428 429 // CommitScriptAnchors return the scripts to use for the local and remote 430 // anchor. 431 func CommitScriptAnchors(localChanCfg, 432 remoteChanCfg *channeldb.ChannelConfig) (*ScriptInfo, 433 *ScriptInfo, error) { 434 435 // Helper to create anchor ScriptInfo from key. 436 anchorScript := func(key *secp256k1.PublicKey) (*ScriptInfo, error) { 437 script, err := input.CommitScriptAnchor(key) 438 if err != nil { 439 return nil, err 440 } 441 442 scriptHash, err := input.ScriptHashPkScript(script) 443 if err != nil { 444 return nil, err 445 } 446 447 return &ScriptInfo{ 448 PkScript: scriptHash, 449 WitnessScript: script, 450 }, nil 451 } 452 453 // Get the script used for the anchor output spendable by the local 454 // node. 455 localAnchor, err := anchorScript(localChanCfg.MultiSigKey.PubKey) 456 if err != nil { 457 return nil, nil, err 458 } 459 460 // And the anchor spendable by the remote node. 461 remoteAnchor, err := anchorScript(remoteChanCfg.MultiSigKey.PubKey) 462 if err != nil { 463 return nil, nil, err 464 } 465 466 return localAnchor, remoteAnchor, nil 467 } 468 469 // CommitmentBuilder is a type that wraps the type of channel we are dealing 470 // with, and abstracts the various ways of constructing commitment 471 // transactions. 472 type CommitmentBuilder struct { 473 // chanState is the underlying channels's state struct, used to 474 // determine the type of channel we are dealing with, and relevant 475 // parameters. 476 chanState *channeldb.OpenChannel 477 478 // obfuscator is a 48-bit state hint that's used to obfuscate the 479 // current state number on the commitment transactions. 480 obfuscator [StateHintSize]byte 481 482 // netParams are the chain parameters for which commitments are built. 483 netParams *chaincfg.Params 484 } 485 486 // NewCommitmentBuilder creates a new CommitmentBuilder from chanState. 487 func NewCommitmentBuilder(chanState *channeldb.OpenChannel, netParams *chaincfg.Params) *CommitmentBuilder { 488 // The anchor channel type MUST be tweakless. 489 if chanState.ChanType.HasAnchors() && !chanState.ChanType.IsTweakless() { 490 panic("invalid channel type combination") 491 } 492 493 return &CommitmentBuilder{ 494 chanState: chanState, 495 obfuscator: createStateHintObfuscator(chanState), 496 netParams: netParams, 497 } 498 } 499 500 // createStateHintObfuscator derives and assigns the state hint obfuscator for 501 // the channel, which is used to encode the commitment height in the sequence 502 // number of commitment transaction inputs. 503 func createStateHintObfuscator(state *channeldb.OpenChannel) [StateHintSize]byte { 504 if state.IsInitiator { 505 return DeriveStateHintObfuscator( 506 state.LocalChanCfg.PaymentBasePoint.PubKey, 507 state.RemoteChanCfg.PaymentBasePoint.PubKey, 508 ) 509 } 510 511 return DeriveStateHintObfuscator( 512 state.RemoteChanCfg.PaymentBasePoint.PubKey, 513 state.LocalChanCfg.PaymentBasePoint.PubKey, 514 ) 515 } 516 517 // unsignedCommitmentTx is the final commitment created from evaluating an HTLC 518 // view at a given height, along with some meta data. 519 type unsignedCommitmentTx struct { 520 // txn is the final, unsigned commitment transaction for this view. 521 txn *wire.MsgTx 522 523 // fee is the total fee of the commitment transaction. 524 fee dcrutil.Amount 525 526 // ourBalance is our balance on this commitment *after* subtracting 527 // commitment fees and anchor outputs. This can be different than the 528 // balances before creating the commitment transaction as one party 529 // must pay the commitment fee. 530 ourBalance lnwire.MilliAtom 531 532 // theirBalance is their balance of this commitment *after* subtracting 533 // commitment fees and anchor outputs. This can be different than the 534 // balances before creating the commitment transaction as one party must 535 // pay the commitment fee. 536 theirBalance lnwire.MilliAtom 537 538 // cltvs is a sorted list of CLTV deltas for each HTLC on the commitment 539 // transaction. Any non-htlc outputs will have a CLTV delay of zero. 540 cltvs []uint32 541 } 542 543 // createUnsignedCommitmentTx generates the unsigned commitment transaction for 544 // a commitment view and returns it as part of the unsignedCommitmentTx. The 545 // passed in balances should be balances *before* subtracting any commitment 546 // fees, but after anchor outputs. 547 func (cb *CommitmentBuilder) createUnsignedCommitmentTx(ourBalance, 548 theirBalance lnwire.MilliAtom, isOurs bool, 549 feePerKB chainfee.AtomPerKByte, height uint64, 550 filteredHTLCView *htlcView, 551 keyRing *CommitmentKeyRing) (*unsignedCommitmentTx, error) { 552 553 dustLimit := cb.chanState.LocalChanCfg.DustLimit 554 if !isOurs { 555 dustLimit = cb.chanState.RemoteChanCfg.DustLimit 556 } 557 558 numHTLCs := int64(0) 559 for _, htlc := range filteredHTLCView.ourUpdates { 560 if HtlcIsDust( 561 cb.chanState.ChanType, false, isOurs, feePerKB, 562 htlc.Amount.ToAtoms(), dustLimit, 563 ) { 564 continue 565 } 566 567 numHTLCs++ 568 } 569 for _, htlc := range filteredHTLCView.theirUpdates { 570 if HtlcIsDust( 571 cb.chanState.ChanType, true, isOurs, feePerKB, 572 htlc.Amount.ToAtoms(), dustLimit, 573 ) { 574 continue 575 } 576 577 numHTLCs++ 578 } 579 580 // Next, we'll calculate the fee for the commitment transaction based 581 // on its total size. Once we have the total size, we'll multiply 582 // by the current fee-per-kb, then divide by 1000 to get the proper 583 // fee. 584 totalCommitSize := CommitSize(cb.chanState.ChanType) + 585 input.HTLCOutputSize*numHTLCs 586 587 // With the size known, we can now calculate the commitment fee, 588 // ensuring that we account for any dust outputs trimmed above. 589 commitFee := feePerKB.FeeForSize(totalCommitSize) 590 commitFeeMAtoms := lnwire.NewMAtomsFromAtoms(commitFee) 591 592 // Currently, within the protocol, the initiator always pays the fees. 593 // So we'll subtract the fee amount from the balance of the current 594 // initiator. If the initiator is unable to pay the fee fully, then 595 // their entire output is consumed. 596 switch { 597 case cb.chanState.IsInitiator && commitFee > ourBalance.ToAtoms(): 598 ourBalance = 0 599 600 case cb.chanState.IsInitiator: 601 ourBalance -= commitFeeMAtoms 602 603 case !cb.chanState.IsInitiator && commitFee > theirBalance.ToAtoms(): 604 theirBalance = 0 605 606 case !cb.chanState.IsInitiator: 607 theirBalance -= commitFeeMAtoms 608 } 609 610 var ( 611 commitTx *wire.MsgTx 612 err error 613 ) 614 615 // Depending on whether the transaction is ours or not, we call 616 // CreateCommitTx with parameters matching the perspective, to generate 617 // a new commitment transaction with all the latest unsettled/un-timed 618 // out HTLCs. 619 var leaseExpiry uint32 620 if cb.chanState.ChanType.HasLeaseExpiration() { 621 leaseExpiry = cb.chanState.ThawHeight 622 } 623 if isOurs { 624 commitTx, err = CreateCommitTx( 625 cb.chanState.ChanType, fundingTxIn(cb.chanState), keyRing, 626 &cb.chanState.LocalChanCfg, &cb.chanState.RemoteChanCfg, 627 ourBalance.ToAtoms(), theirBalance.ToAtoms(), 628 numHTLCs, cb.chanState.IsInitiator, leaseExpiry, 629 ) 630 } else { 631 commitTx, err = CreateCommitTx( 632 cb.chanState.ChanType, fundingTxIn(cb.chanState), keyRing, 633 &cb.chanState.RemoteChanCfg, &cb.chanState.LocalChanCfg, 634 theirBalance.ToAtoms(), ourBalance.ToAtoms(), 635 numHTLCs, !cb.chanState.IsInitiator, leaseExpiry, 636 ) 637 } 638 if err != nil { 639 return nil, err 640 } 641 642 // We'll now add all the HTLC outputs to the commitment transaction. 643 // Each output includes an off-chain 2-of-2 covenant clause, so we'll 644 // need the objective local/remote keys for this particular commitment 645 // as well. For any non-dust HTLCs that are manifested on the commitment 646 // transaction, we'll also record its CLTV which is required to sort the 647 // commitment transaction below. The slice is initially sized to the 648 // number of existing outputs, since any outputs already added are 649 // commitment outputs and should correspond to zero values for the 650 // purposes of sorting. 651 cltvs := make([]uint32, len(commitTx.TxOut)) 652 for _, htlc := range filteredHTLCView.ourUpdates { 653 if HtlcIsDust( 654 cb.chanState.ChanType, false, isOurs, feePerKB, 655 htlc.Amount.ToAtoms(), dustLimit, 656 ) { 657 continue 658 } 659 660 err := addHTLC( 661 commitTx, isOurs, false, htlc, keyRing, 662 cb.chanState.ChanType, 663 ) 664 if err != nil { 665 return nil, err 666 } 667 cltvs = append(cltvs, htlc.Timeout) 668 } 669 for _, htlc := range filteredHTLCView.theirUpdates { 670 if HtlcIsDust( 671 cb.chanState.ChanType, true, isOurs, feePerKB, 672 htlc.Amount.ToAtoms(), dustLimit, 673 ) { 674 continue 675 } 676 677 err := addHTLC( 678 commitTx, isOurs, true, htlc, keyRing, 679 cb.chanState.ChanType, 680 ) 681 if err != nil { 682 return nil, err 683 } 684 cltvs = append(cltvs, htlc.Timeout) 685 } 686 687 // Set the state hint of the commitment transaction to facilitate 688 // quickly recovering the necessary penalty state in the case of an 689 // uncooperative broadcast. 690 err = SetStateNumHint(commitTx, height, cb.obfuscator) 691 if err != nil { 692 return nil, err 693 } 694 695 // Sort the transactions according to the agreed upon canonical 696 // ordering. This lets us skip sending the entire transaction over, 697 // instead we'll just send signatures. 698 InPlaceCommitSort(commitTx, cltvs) 699 700 // Next, we'll ensure that we don't accidentally create a commitment 701 // transaction which would be invalid by consensus. 702 if err := standalone.CheckTransactionSanity(commitTx, uint64(cb.netParams.MaxTxSize)); err != nil { 703 return nil, err 704 } 705 706 // Finally, we'll assert that were not attempting to draw more out of 707 // the channel that was originally placed within it. 708 var totalOut dcrutil.Amount 709 for _, txOut := range commitTx.TxOut { 710 totalOut += dcrutil.Amount(txOut.Value) 711 } 712 if totalOut+commitFee > cb.chanState.Capacity { 713 return nil, fmt.Errorf("height=%v, for ChannelPoint(%v) "+ 714 "attempts to consume %v while channel capacity is %v", 715 height, cb.chanState.FundingOutpoint, 716 totalOut+commitFee, cb.chanState.Capacity) 717 } 718 719 return &unsignedCommitmentTx{ 720 txn: commitTx, 721 fee: commitFee, 722 ourBalance: ourBalance, 723 theirBalance: theirBalance, 724 cltvs: cltvs, 725 }, nil 726 } 727 728 // CreateCommitTx creates a commitment transaction, spending from specified 729 // funding output. The commitment transaction contains two outputs: one local 730 // output paying to the "owner" of the commitment transaction which can be 731 // spent after a relative block delay or revocation event, and a remote output 732 // paying the counterparty within the channel, which can be spent immediately 733 // or after a delay depending on the commitment type. The `initiator` argument 734 // should correspond to the owner of the commitment tranasction we are creating. 735 func CreateCommitTx(chanType channeldb.ChannelType, 736 fundingOutput wire.TxIn, keyRing *CommitmentKeyRing, 737 localChanCfg, remoteChanCfg *channeldb.ChannelConfig, 738 amountToLocal, amountToRemote dcrutil.Amount, 739 numHTLCs int64, initiator bool, leaseExpiry uint32) (*wire.MsgTx, error) { 740 741 // First, we create the script for the delayed "pay-to-self" output. 742 // This output has 2 main redemption clauses: either we can redeem the 743 // output after a relative block delay, or the remote node can claim 744 // the funds with the revocation key if we broadcast a revoked 745 // commitment transaction. 746 toLocalScript, err := CommitScriptToSelf( 747 chanType, initiator, keyRing.ToLocalKey, keyRing.RevocationKey, 748 uint32(localChanCfg.CsvDelay), leaseExpiry, 749 ) 750 if err != nil { 751 return nil, err 752 } 753 754 // Next, we create the script paying to the remote. 755 toRemoteScript, _, err := CommitScriptToRemote( 756 chanType, initiator, keyRing.ToRemoteKey, leaseExpiry, 757 ) 758 if err != nil { 759 return nil, err 760 } 761 762 // Now that both output scripts have been created, we can finally create 763 // the transaction itself. We use a transaction version of 2 since CSV 764 // will fail unless the tx version is >= 2. 765 commitTx := wire.NewMsgTx() 766 commitTx.Version = input.LNTxVersion 767 commitTx.AddTxIn(&fundingOutput) 768 769 // Avoid creating dust outputs within the commitment transaction. 770 localOutput := amountToLocal >= localChanCfg.DustLimit 771 if localOutput { 772 commitTx.AddTxOut(&wire.TxOut{ 773 PkScript: toLocalScript.PkScript, 774 Value: int64(amountToLocal), 775 Version: scriptVersion, 776 }) 777 } 778 779 remoteOutput := amountToRemote >= localChanCfg.DustLimit 780 if remoteOutput { 781 commitTx.AddTxOut(&wire.TxOut{ 782 PkScript: toRemoteScript.PkScript, 783 Value: int64(amountToRemote), 784 Version: scriptVersion, 785 }) 786 } 787 788 // If this channel type has anchors, we'll also add those. 789 if chanType.HasAnchors() { 790 localAnchor, remoteAnchor, err := CommitScriptAnchors( 791 localChanCfg, remoteChanCfg, 792 ) 793 if err != nil { 794 return nil, err 795 } 796 797 // Add local anchor output only if we have a commitment output 798 // or there are HTLCs. 799 if localOutput || numHTLCs > 0 { 800 commitTx.AddTxOut(&wire.TxOut{ 801 PkScript: localAnchor.PkScript, 802 Value: int64(anchorSize), 803 }) 804 } 805 806 // Add anchor output to remote only if they have a commitment 807 // output or there are HTLCs. 808 if remoteOutput || numHTLCs > 0 { 809 commitTx.AddTxOut(&wire.TxOut{ 810 PkScript: remoteAnchor.PkScript, 811 Value: int64(anchorSize), 812 }) 813 } 814 } 815 816 return commitTx, nil 817 } 818 819 // CoopCloseBalance returns the final balances that should be used to create 820 // the cooperative close tx, given the channel type and transaction fee. 821 func CoopCloseBalance(chanType channeldb.ChannelType, isInitiator bool, 822 coopCloseFee dcrutil.Amount, localCommit channeldb.ChannelCommitment) ( 823 dcrutil.Amount, dcrutil.Amount, error) { 824 825 // Get both parties' balances from the latest commitment. 826 ourBalance := localCommit.LocalBalance.ToAtoms() 827 theirBalance := localCommit.RemoteBalance.ToAtoms() 828 829 // We'll make sure we account for the complete balance by adding the 830 // current dangling commitment fee to the balance of the initiator. 831 initiatorDelta := localCommit.CommitFee 832 833 // Since the initiator's balance also is stored after subtracting the 834 // anchor values, add that back in case this was an anchor commitment. 835 if chanType.HasAnchors() { 836 initiatorDelta += 2 * anchorSize 837 } 838 839 // The initiator will pay the full coop close fee, subtract that value 840 // from their balance. 841 initiatorDelta -= coopCloseFee 842 843 if isInitiator { 844 ourBalance += initiatorDelta 845 } else { 846 theirBalance += initiatorDelta 847 } 848 849 // During fee negotiation it should always be verified that the 850 // initiator can pay the proposed fee, but we do a sanity check just to 851 // be sure here. 852 if ourBalance < 0 || theirBalance < 0 { 853 return 0, 0, fmt.Errorf("initiator cannot afford proposed " + 854 "coop close fee") 855 } 856 857 return ourBalance, theirBalance, nil 858 } 859 860 // genHtlcScript generates the proper P2SH public key scripts for the HTLC 861 // output modified by two-bits denoting if this is an incoming HTLC, and if the 862 // HTLC is being applied to their commitment transaction or ours. 863 func genHtlcScript(chanType channeldb.ChannelType, isIncoming, ourCommit bool, 864 timeout uint32, rHash [32]byte, 865 keyRing *CommitmentKeyRing) ([]byte, []byte, error) { 866 867 var ( 868 witnessScript []byte 869 err error 870 ) 871 872 // Choose scripts based on channel type. 873 confirmedHtlcSpends := false 874 if chanType.HasAnchors() { 875 confirmedHtlcSpends = true 876 } 877 878 // Generate the proper redeem scripts for the HTLC output modified by 879 // two-bits denoting if this is an incoming HTLC, and if the HTLC is 880 // being applied to their commitment transaction or ours. 881 switch { 882 // The HTLC is paying to us, and being applied to our commitment 883 // transaction. So we need to use the receiver's version of HTLC the 884 // script. 885 case isIncoming && ourCommit: 886 witnessScript, err = input.ReceiverHTLCScript( 887 timeout, keyRing.RemoteHtlcKey, keyRing.LocalHtlcKey, 888 keyRing.RevocationKey, rHash[:], confirmedHtlcSpends, 889 ) 890 891 // We're being paid via an HTLC by the remote party, and the HTLC is 892 // being added to their commitment transaction, so we use the sender's 893 // version of the HTLC script. 894 case isIncoming && !ourCommit: 895 witnessScript, err = input.SenderHTLCScript( 896 keyRing.RemoteHtlcKey, keyRing.LocalHtlcKey, 897 keyRing.RevocationKey, rHash[:], confirmedHtlcSpends, 898 ) 899 900 // We're sending an HTLC which is being added to our commitment 901 // transaction. Therefore, we need to use the sender's version of the 902 // HTLC script. 903 case !isIncoming && ourCommit: 904 witnessScript, err = input.SenderHTLCScript( 905 keyRing.LocalHtlcKey, keyRing.RemoteHtlcKey, 906 keyRing.RevocationKey, rHash[:], confirmedHtlcSpends, 907 ) 908 909 // Finally, we're paying the remote party via an HTLC, which is being 910 // added to their commitment transaction. Therefore, we use the 911 // receiver's version of the HTLC script. 912 case !isIncoming && !ourCommit: 913 witnessScript, err = input.ReceiverHTLCScript( 914 timeout, keyRing.LocalHtlcKey, keyRing.RemoteHtlcKey, 915 keyRing.RevocationKey, rHash[:], confirmedHtlcSpends, 916 ) 917 } 918 if err != nil { 919 return nil, nil, err 920 } 921 922 // Now that we have the redeem scripts, create the P2WSH public key 923 // script for the output itself. 924 htlcP2SH, err := input.ScriptHashPkScript(witnessScript) 925 if err != nil { 926 return nil, nil, err 927 } 928 929 return htlcP2SH, witnessScript, nil 930 } 931 932 // addHTLC adds a new HTLC to the passed commitment transaction. One of four 933 // full scripts will be generated for the HTLC output depending on if the HTLC 934 // is incoming and if it's being applied to our commitment transaction or that 935 // of the remote node's. Additionally, in order to be able to efficiently 936 // locate the added HTLC on the commitment transaction from the 937 // PaymentDescriptor that generated it, the generated script is stored within 938 // the descriptor itself. 939 func addHTLC(commitTx *wire.MsgTx, ourCommit bool, 940 isIncoming bool, paymentDesc *PaymentDescriptor, 941 keyRing *CommitmentKeyRing, chanType channeldb.ChannelType) error { 942 943 timeout := paymentDesc.Timeout 944 rHash := paymentDesc.RHash 945 946 p2sh, witnessScript, err := genHtlcScript( 947 chanType, isIncoming, ourCommit, timeout, rHash, keyRing, 948 ) 949 if err != nil { 950 return err 951 } 952 953 // Add the new HTLC outputs to the respective commitment transactions. 954 amountPending := int64(paymentDesc.Amount.ToAtoms()) 955 commitTx.AddTxOut(wire.NewTxOut(amountPending, p2sh)) 956 957 // Store the pkScript of this particular PaymentDescriptor so we can 958 // quickly locate it within the commitment transaction later. 959 if ourCommit { 960 paymentDesc.ourPkScript = p2sh 961 paymentDesc.ourWitnessScript = witnessScript 962 } else { 963 paymentDesc.theirPkScript = p2sh 964 paymentDesc.theirWitnessScript = witnessScript 965 } 966 967 return nil 968 }