mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-08-07 12:32:29 +02:00
lnwallet: update CreateHtlcTimeoutTx+CreateHtlcSuccessTx for taproot
This commit is contained in:
@@ -410,26 +410,47 @@ func SecondLevelHtlcScript(chanType channeldb.ChannelType, initiator bool,
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
witnessScript []byte
|
witnessScript []byte
|
||||||
|
pkScript []byte
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
switch {
|
switch {
|
||||||
|
// For taproot channels, the pkScript is a segwit v1 p2tr output.
|
||||||
|
case chanType.IsTaproot():
|
||||||
|
taprootOutputKey, err := input.TaprootSecondLevelHtlcScript(
|
||||||
|
revocationKey, delayKey, csvDelay,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pkScript, err = input.PayToTaprootScript(taprootOutputKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// If we are the initiator of a leased channel, then we have an
|
// If we are the initiator of a leased channel, then we have an
|
||||||
// additional CLTV requirement in addition to the usual CSV requirement.
|
// additional CLTV requirement in addition to the usual CSV
|
||||||
|
// requirement.
|
||||||
case initiator && chanType.HasLeaseExpiration():
|
case initiator && chanType.HasLeaseExpiration():
|
||||||
witnessScript, err = input.LeaseSecondLevelHtlcScript(
|
witnessScript, err = input.LeaseSecondLevelHtlcScript(
|
||||||
revocationKey, delayKey, csvDelay, leaseExpiry,
|
revocationKey, delayKey, csvDelay, leaseExpiry,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
pkScript, err = input.WitnessScriptHash(witnessScript)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
witnessScript, err = input.SecondLevelHtlcScript(
|
witnessScript, err = input.SecondLevelHtlcScript(
|
||||||
revocationKey, delayKey, csvDelay,
|
revocationKey, delayKey, csvDelay,
|
||||||
)
|
)
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pkScript, err := input.WitnessScriptHash(witnessScript)
|
pkScript, err = input.WitnessScriptHash(witnessScript)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/btcsuite/btcd/btcutil"
|
"github.com/btcsuite/btcd/btcutil"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
|
"github.com/lightningnetwork/lnd/input"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -41,9 +42,13 @@ var (
|
|||||||
// state transition to create another output which actually allows redemption
|
// state transition to create another output which actually allows redemption
|
||||||
// or revocation of an HTLC.
|
// or revocation of an HTLC.
|
||||||
//
|
//
|
||||||
// In order to spend the HTLC output, the witness for the passed transaction
|
// In order to spend the segwit v0 HTLC output, the witness for the passed
|
||||||
// should be:
|
// transaction should be:
|
||||||
// - <0> <sender sig> <recvr sig> <preimage>
|
// - <0> <sender sig> <recvr sig> <preimage>
|
||||||
|
//
|
||||||
|
// In order to spend the segwit v1 (taproot) HTLC output, the witness for the
|
||||||
|
// passed transaction should be:
|
||||||
|
// - <sender sig> <receiver sig> <preimage> <sucess_script> <control_block>
|
||||||
func CreateHtlcSuccessTx(chanType channeldb.ChannelType, initiator bool,
|
func CreateHtlcSuccessTx(chanType channeldb.ChannelType, initiator bool,
|
||||||
htlcOutput wire.OutPoint, htlcAmt btcutil.Amount, csvDelay,
|
htlcOutput wire.OutPoint, htlcAmt btcutil.Amount, csvDelay,
|
||||||
leaseExpiry uint32, revocationKey, delayKey *btcec.PublicKey) (
|
leaseExpiry uint32, revocationKey, delayKey *btcec.PublicKey) (
|
||||||
@@ -62,10 +67,12 @@ func CreateHtlcSuccessTx(chanType channeldb.ChannelType, initiator bool,
|
|||||||
}
|
}
|
||||||
successTx.AddTxIn(txin)
|
successTx.AddTxIn(txin)
|
||||||
|
|
||||||
|
var pkScript []byte
|
||||||
|
|
||||||
// Next, we'll generate the script used as the output for all second
|
// Next, we'll generate the script used as the output for all second
|
||||||
// level HTLC which forces a covenant w.r.t what can be done with all
|
// level HTLC which forces a covenant w.r.t what can be done with all
|
||||||
// HTLC outputs.
|
// HTLC outputs.
|
||||||
script, err := SecondLevelHtlcScript(
|
scriptInfo, err := SecondLevelHtlcScript(
|
||||||
chanType, initiator, revocationKey, delayKey, csvDelay,
|
chanType, initiator, revocationKey, delayKey, csvDelay,
|
||||||
leaseExpiry,
|
leaseExpiry,
|
||||||
)
|
)
|
||||||
@@ -73,11 +80,13 @@ func CreateHtlcSuccessTx(chanType channeldb.ChannelType, initiator bool,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pkScript = scriptInfo.PkScript
|
||||||
|
|
||||||
// Finally, the output is simply the amount of the HTLC (minus the
|
// Finally, the output is simply the amount of the HTLC (minus the
|
||||||
// required fees), paying to the timeout script.
|
// required fees), paying to the timeout script.
|
||||||
successTx.AddTxOut(&wire.TxOut{
|
successTx.AddTxOut(&wire.TxOut{
|
||||||
Value: int64(htlcAmt),
|
Value: int64(htlcAmt),
|
||||||
PkScript: script.PkScript,
|
PkScript: pkScript,
|
||||||
})
|
})
|
||||||
|
|
||||||
return successTx, nil
|
return successTx, nil
|
||||||
@@ -92,9 +101,13 @@ func CreateHtlcSuccessTx(chanType channeldb.ChannelType, initiator bool,
|
|||||||
// transaction is locked with an absolute lock-time so the sender can only
|
// transaction is locked with an absolute lock-time so the sender can only
|
||||||
// attempt to claim the output using it after the lock time has passed.
|
// attempt to claim the output using it after the lock time has passed.
|
||||||
//
|
//
|
||||||
// In order to spend the HTLC output, the witness for the passed transaction
|
// In order to spend the HTLC output for segwit v0, the witness for the passed
|
||||||
// should be:
|
// transaction should be:
|
||||||
// * <0> <sender sig> <receiver sig> <0>
|
// - <0> <sender sig> <receiver sig> <0>
|
||||||
|
//
|
||||||
|
// In order to spend the HTLC output for segwit v1, then witness for the passed
|
||||||
|
// transaction should be:
|
||||||
|
// - <sender sig> <receiver sig> <timeout_script> <control_block>
|
||||||
//
|
//
|
||||||
// NOTE: The passed amount for the HTLC should take into account the required
|
// NOTE: The passed amount for the HTLC should take into account the required
|
||||||
// fee rate at the time the HTLC was created. The fee should be able to
|
// fee rate at the time the HTLC was created. The fee should be able to
|
||||||
@@ -121,22 +134,43 @@ func CreateHtlcTimeoutTx(chanType channeldb.ChannelType, initiator bool,
|
|||||||
}
|
}
|
||||||
timeoutTx.AddTxIn(txin)
|
timeoutTx.AddTxIn(txin)
|
||||||
|
|
||||||
// Next, we'll generate the script used as the output for all second
|
var pkScript []byte
|
||||||
// level HTLC which forces a covenant w.r.t what can be done with all
|
|
||||||
// HTLC outputs.
|
// Depending on if this is a taproot channel or not, we'll create a v0
|
||||||
script, err := SecondLevelHtlcScript(
|
// vs v1 segwit script.
|
||||||
chanType, initiator, revocationKey, delayKey, csvDelay,
|
if chanType.IsTaproot() {
|
||||||
leaseExpiry,
|
taprootOutputKey, err := input.TaprootSecondLevelHtlcScript(
|
||||||
)
|
revocationKey, delayKey, csvDelay,
|
||||||
if err != nil {
|
)
|
||||||
return nil, err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pkScript, err = input.PayToTaprootScript(taprootOutputKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Next, we'll generate the script used as the output for all second
|
||||||
|
// level HTLC which forces a covenant w.r.t what can be done with all
|
||||||
|
// HTLC outputs.
|
||||||
|
scriptInfo, err := SecondLevelHtlcScript(
|
||||||
|
chanType, initiator, revocationKey, delayKey, csvDelay,
|
||||||
|
leaseExpiry,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pkScript = scriptInfo.PkScript
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, the output is simply the amount of the HTLC (minus the
|
// Finally, the output is simply the amount of the HTLC (minus the
|
||||||
// required fees), paying to the regular second level HTLC script.
|
// required fees), paying to the regular second level HTLC script.
|
||||||
timeoutTx.AddTxOut(&wire.TxOut{
|
timeoutTx.AddTxOut(&wire.TxOut{
|
||||||
Value: int64(htlcAmt),
|
Value: int64(htlcAmt),
|
||||||
PkScript: script.PkScript,
|
PkScript: pkScript,
|
||||||
})
|
})
|
||||||
|
|
||||||
return timeoutTx, nil
|
return timeoutTx, nil
|
||||||
|
Reference in New Issue
Block a user