// receiverHtlcSpendTimeout constructs a valid witness allowing the sender of // an HTLC to recover the pending funds after an absolute timeout in the // scenario that the receiver of the HTLC broadcasts their version of the // commitment transaction. func receiverHtlcSpendTimeout(commitScript []byte, outputAmt btcutil.Amount, senderKey *btcec.PrivateKey, sweepTx *wire.MsgTx, absoluteTimeout uint32) (wire.TxWitness, error) { // The HTLC output has an absolute time period before we are permitted // to recover the pending funds. Therefore we need to set the locktime // on this sweeping transaction in order to pass Script verification. sweepTx.LockTime = absoluteTimeout hashCache := txscript.NewTxSigHashes(sweepTx) sweepSig, err := txscript.RawTxInWitnessSignature( sweepTx, hashCache, 0, int64(outputAmt), commitScript, txscript.SigHashAll, senderKey) if err != nil { return nil, err } witnessStack := wire.TxWitness(make([][]byte, 4)) witnessStack[0] = sweepSig witnessStack[1] = []byte{0} witnessStack[2] = []byte{0} witnessStack[3] = commitScript return witnessStack, nil }
// htlcSpendTimeout constructs a valid witness allowing the sender of an HTLC // to recover the pending funds after an absolute, then relative locktime // period. func senderHtlcSpendTimeout(commitScript []byte, outputAmt btcutil.Amount, senderKey *btcec.PrivateKey, sweepTx *wire.MsgTx, absoluteTimeout, relativeTimeout uint32) (wire.TxWitness, error) { // Since the HTLC output has an absolute timeout before we're permitted // to sweep the output, we need to set the locktime of this sweepign // transaction to that aboslute value in order to pass Script // verification. sweepTx.LockTime = absoluteTimeout // Additionally, we're required to wait a relative period of time // before we can sweep the output in order to allow the other party to // contest our claim of validity to this version of the commitment // transaction. sweepTx.TxIn[0].Sequence = lockTimeToSequence(false, relativeTimeout) // Finally, OP_CSV requires that the version of the transaction // spending a pkscript with OP_CSV within it *must* be >= 2. sweepTx.Version = 2 hashCache := txscript.NewTxSigHashes(sweepTx) sweepSig, err := txscript.RawTxInWitnessSignature( sweepTx, hashCache, 0, int64(outputAmt), commitScript, txscript.SigHashAll, senderKey) if err != nil { return nil, err } // We place a zero as the first item of the evaluated witness stack in // order to force Script execution to the HTLC timeout clause. witnessStack := wire.TxWitness(make([][]byte, 3)) witnessStack[0] = sweepSig witnessStack[1] = []byte{0} witnessStack[2] = commitScript return witnessStack, nil }