lnd/input/witnessgen.go
2023-08-22 16:34:15 -07:00

893 lines
28 KiB
Go

package input
import (
"fmt"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
)
// WitnessGenerator represents a function that is able to generate the final
// witness for a particular public key script. Additionally, if required, this
// function will also return the sigScript for spending nested P2SH witness
// outputs. This function acts as an abstraction layer, hiding the details of
// the underlying script.
type WitnessGenerator func(tx *wire.MsgTx, hc *txscript.TxSigHashes,
inputIndex int) (*Script, error)
// WitnessType determines how an output's witness will be generated. This
// interface can be implemented to be used for custom sweep scripts if the
// pre-defined StandardWitnessType list doesn't provide a suitable one.
type WitnessType interface {
// String returns a human readable version of the WitnessType.
String() string
// WitnessGenerator will return a WitnessGenerator function that an
// output uses to generate the witness and optionally the sigScript for
// a sweep transaction.
WitnessGenerator(signer Signer,
descriptor *SignDescriptor) WitnessGenerator
// SizeUpperBound returns the maximum length of the witness of this
// WitnessType if it would be included in a tx. It also returns if the
// output itself is a nested p2sh output, if so then we need to take
// into account the extra sigScript data size.
SizeUpperBound() (int, bool, error)
// AddWeightEstimation adds the estimated size of the witness in bytes
// to the given weight estimator.
AddWeightEstimation(e *TxWeightEstimator) error
}
// StandardWitnessType is a numeric representation of standard pre-defined types
// of witness configurations.
type StandardWitnessType uint16
// A compile time check to ensure StandardWitnessType implements the
// WitnessType interface.
var _ WitnessType = (StandardWitnessType)(0)
// NOTE: When adding a new `StandardWitnessType`, also update the `WitnessType`
// protobuf enum and the `allWitnessTypes` map in the `walletrpc` package.
const (
// CommitmentTimeLock is a witness that allows us to spend our output
// on our local commitment transaction after a relative lock-time
// lockout.
CommitmentTimeLock StandardWitnessType = 0
// CommitmentNoDelay is a witness that allows us to spend a settled
// no-delay output immediately on a counterparty's commitment
// transaction.
CommitmentNoDelay StandardWitnessType = 1
// CommitmentRevoke is a witness that allows us to sweep the settled
// output of a malicious counterparty's who broadcasts a revoked
// commitment transaction.
CommitmentRevoke StandardWitnessType = 2
// HtlcOfferedRevoke is a witness that allows us to sweep an HTLC which
// we offered to the remote party in the case that they broadcast a
// revoked commitment state.
HtlcOfferedRevoke StandardWitnessType = 3
// HtlcAcceptedRevoke is a witness that allows us to sweep an HTLC
// output sent to us in the case that the remote party broadcasts a
// revoked commitment state.
HtlcAcceptedRevoke StandardWitnessType = 4
// HtlcOfferedTimeoutSecondLevel is a witness that allows us to sweep
// an HTLC output that we extended to a party, but was never fulfilled.
// This HTLC output isn't directly on the commitment transaction, but
// is the result of a confirmed second-level HTLC transaction. As a
// result, we can only spend this after a CSV delay.
HtlcOfferedTimeoutSecondLevel StandardWitnessType = 5
// HtlcOfferedTimeoutSecondLevelInputConfirmed is a witness that allows
// us to sweep an HTLC output that we extended to a party, but was
// never fulfilled. This _is_ the HTLC output directly on our
// commitment transaction, and the input to the second-level HTLC
// timeout transaction. It can only be spent after CLTV expiry, and
// commitment confirmation.
HtlcOfferedTimeoutSecondLevelInputConfirmed StandardWitnessType = 15
// HtlcAcceptedSuccessSecondLevel is a witness that allows us to sweep
// an HTLC output that was offered to us, and for which we have a
// payment preimage. This HTLC output isn't directly on our commitment
// transaction, but is the result of confirmed second-level HTLC
// transaction. As a result, we can only spend this after a CSV delay.
HtlcAcceptedSuccessSecondLevel StandardWitnessType = 6
// HtlcAcceptedSuccessSecondLevelInputConfirmed is a witness that
// allows us to sweep an HTLC output that was offered to us, and for
// which we have a payment preimage. This _is_ the HTLC output directly
// on our commitment transaction, and the input to the second-level
// HTLC success transaction. It can only be spent after the commitment
// has confirmed.
HtlcAcceptedSuccessSecondLevelInputConfirmed StandardWitnessType = 16
// HtlcOfferedRemoteTimeout is a witness that allows us to sweep an
// HTLC that we offered to the remote party which lies in the
// commitment transaction of the remote party. We can spend this output
// after the absolute CLTV timeout of the HTLC as passed.
HtlcOfferedRemoteTimeout StandardWitnessType = 7
// HtlcAcceptedRemoteSuccess is a witness that allows us to sweep an
// HTLC that was offered to us by the remote party. We use this witness
// in the case that the remote party goes to chain, and we know the
// pre-image to the HTLC. We can sweep this without any additional
// timeout.
HtlcAcceptedRemoteSuccess StandardWitnessType = 8
// HtlcSecondLevelRevoke is a witness that allows us to sweep an HTLC
// from the remote party's commitment transaction in the case that the
// broadcast a revoked commitment, but then also immediately attempt to
// go to the second level to claim the HTLC.
HtlcSecondLevelRevoke StandardWitnessType = 9
// WitnessKeyHash is a witness type that allows us to spend a regular
// p2wkh output that's sent to an output which is under complete
// control of the backing wallet.
WitnessKeyHash StandardWitnessType = 10
// NestedWitnessKeyHash is a witness type that allows us to sweep an
// output that sends to a nested P2SH script that pays to a key solely
// under our control. The witness generated needs to include the
NestedWitnessKeyHash StandardWitnessType = 11
// CommitSpendNoDelayTweakless is similar to the CommitSpendNoDelay
// type, but it omits the tweak that randomizes the key we need to
// spend with a channel peer supplied set of randomness.
CommitSpendNoDelayTweakless StandardWitnessType = 12
// CommitmentToRemoteConfirmed is a witness that allows us to spend our
// output on the counterparty's commitment transaction after a
// confirmation.
CommitmentToRemoteConfirmed StandardWitnessType = 13
// CommitmentAnchor is a witness that allows us to spend our anchor on
// the commitment transaction.
CommitmentAnchor StandardWitnessType = 14
// LeaseCommitmentTimeLock is a witness that allows us to spend our
// output on our local commitment transaction after a relative and
// absolute lock-time lockout as part of the script enforced lease
// commitment type.
LeaseCommitmentTimeLock StandardWitnessType = 17
// LeaseCommitmentToRemoteConfirmed is a witness that allows us to spend
// our output on the counterparty's commitment transaction after a
// confirmation and absolute locktime as part of the script enforced
// lease commitment type.
LeaseCommitmentToRemoteConfirmed StandardWitnessType = 18
// LeaseHtlcOfferedTimeoutSecondLevel is a witness that allows us to
// sweep an HTLC output that we extended to a party, but was never
// fulfilled. This HTLC output isn't directly on the commitment
// transaction, but is the result of a confirmed second-level HTLC
// transaction. As a result, we can only spend this after a CSV delay
// and CLTV locktime as part of the script enforced lease commitment
// type.
LeaseHtlcOfferedTimeoutSecondLevel StandardWitnessType = 19
// LeaseHtlcAcceptedSuccessSecondLevel is a witness that allows us to
// sweep an HTLC output that was offered to us, and for which we have a
// payment preimage. This HTLC output isn't directly on our commitment
// transaction, but is the result of confirmed second-level HTLC
// transaction. As a result, we can only spend this after a CSV delay
// and CLTV locktime as part of the script enforced lease commitment
// type.
LeaseHtlcAcceptedSuccessSecondLevel StandardWitnessType = 20
// TaprootPubKeySpend is a witness type that allows us to spend a
// regular p2tr output that's sent to an output which is under complete
// control of the backing wallet.
TaprootPubKeySpend StandardWitnessType = 21
// TaprootLocalCommitSpend is a witness type that allows us to spend
// our settled local commitment after a CSV delay when we force close
// the channel.
TaprootLocalCommitSpend StandardWitnessType = 22
// TaprootRemoteCommitSpend is a witness type that allows us to spend
// our settled local commitment after a CSV delay when the remote party
// has force closed the channel.
TaprootRemoteCommitSpend StandardWitnessType = 23
// TaprootAnchorSweepSpend is the witness type we'll use for spending
// our own anchor output.
TaprootAnchorSweepSpend StandardWitnessType = 24
// TaprootHtlcOfferedTimeoutSecondLevel is a witness that allows us to
// timeout an HTLC we offered to the remote party on our commitment
// transaction. We use this when we need to go on chain to time out an
// HTLC.
TaprootHtlcOfferedTimeoutSecondLevel StandardWitnessType = 25
// TaprootHtlcAcceptedSuccessSecondLevel is a witness that allows us to
// sweep an HTLC we accepted on our commitment transaction after we go
// to the second level on chain.
TaprootHtlcAcceptedSuccessSecondLevel StandardWitnessType = 26
// TaprootHtlcSecondLevelRevoke is a witness that allows us to sweep an
// HTLC on the revoked transaction of the remote party that goes to the
// second level.
TaprootHtlcSecondLevelRevoke StandardWitnessType = 27
// TaprootHtlcAcceptedRevoke is a witness that allows us to sweep an
// HTLC sent to us by the remote party in the event that they broadcast
// a revoked state.
TaprootHtlcAcceptedRevoke StandardWitnessType = 28
// TaprootHtlcOfferedRevoke is a witness that allows us to sweep an
// HTLC we offered to the remote party if they broadcast a revoked
// commitment.
TaprootHtlcOfferedRevoke StandardWitnessType = 29
// TaprootHtlcOfferedRemoteTimeout is a witness that allows us to sweep
// an HTLC we offered to the remote party that lies on the commitment
// transaction for the remote party. We can spend this output after the
// absolute CLTV timeout of the HTLC as passed.
TaprootHtlcOfferedRemoteTimeout StandardWitnessType = 30
// TaprootHtlcLocalOfferedTimeout is a witness type that allows us to
// sign the second level HTLC timeout transaction when spending from an
// HTLC residing on our local commitment transaction.
//
// This is used by the sweeper to re-sign inputs if it needs to
// aggregate several second level HTLCs.
TaprootHtlcLocalOfferedTimeout StandardWitnessType = 31
// TaprootHtlcAcceptedRemoteSuccess is a witness that allows us to
// sweep an HTLC that was offered to us by the remote party for a
// taproot channels. We use this witness in the case that the remote
// party goes to chain, and we know the pre-image to the HTLC. We can
// sweep this without any additional timeout.
TaprootHtlcAcceptedRemoteSuccess StandardWitnessType = 32
// TaprootHtlcAcceptedLocalSuccess is a witness type that allows us to
// sweep the HTLC offered to us on our local commitment transaction.
// We'll use this when we need to go on chain to sweep the HTLC. In
// this case, this is the second level HTLC success transaction.
TaprootHtlcAcceptedLocalSuccess StandardWitnessType = 33
// TaprootCommitmentRevoke is a witness that allows us to sweep the
// settled output of a malicious counterparty's who broadcasts a
// revoked taproot commitment transaction.
TaprootCommitmentRevoke StandardWitnessType = 34
)
// String returns a human readable version of the target WitnessType.
//
// NOTE: This is part of the WitnessType interface.
func (wt StandardWitnessType) String() string {
switch wt {
case CommitmentTimeLock:
return "CommitmentTimeLock"
case CommitmentToRemoteConfirmed:
return "CommitmentToRemoteConfirmed"
case CommitmentAnchor:
return "CommitmentAnchor"
case CommitmentNoDelay:
return "CommitmentNoDelay"
case CommitSpendNoDelayTweakless:
return "CommitmentNoDelayTweakless"
case CommitmentRevoke:
return "CommitmentRevoke"
case HtlcOfferedRevoke:
return "HtlcOfferedRevoke"
case HtlcAcceptedRevoke:
return "HtlcAcceptedRevoke"
case HtlcOfferedTimeoutSecondLevel:
return "HtlcOfferedTimeoutSecondLevel"
case HtlcOfferedTimeoutSecondLevelInputConfirmed:
return "HtlcOfferedTimeoutSecondLevelInputConfirmed"
case HtlcAcceptedSuccessSecondLevel:
return "HtlcAcceptedSuccessSecondLevel"
case HtlcAcceptedSuccessSecondLevelInputConfirmed:
return "HtlcAcceptedSuccessSecondLevelInputConfirmed"
case HtlcOfferedRemoteTimeout:
return "HtlcOfferedRemoteTimeout"
case HtlcAcceptedRemoteSuccess:
return "HtlcAcceptedRemoteSuccess"
case HtlcSecondLevelRevoke:
return "HtlcSecondLevelRevoke"
case WitnessKeyHash:
return "WitnessKeyHash"
case NestedWitnessKeyHash:
return "NestedWitnessKeyHash"
case LeaseCommitmentTimeLock:
return "LeaseCommitmentTimeLock"
case LeaseCommitmentToRemoteConfirmed:
return "LeaseCommitmentToRemoteConfirmed"
case LeaseHtlcOfferedTimeoutSecondLevel:
return "LeaseHtlcOfferedTimeoutSecondLevel"
case LeaseHtlcAcceptedSuccessSecondLevel:
return "LeaseHtlcAcceptedSuccessSecondLevel"
case TaprootPubKeySpend:
return "TaprootPubKeySpend"
case TaprootLocalCommitSpend:
return "TaprootLocalCommitSpend"
case TaprootRemoteCommitSpend:
return "TaprootRemoteCommitSpend"
case TaprootAnchorSweepSpend:
return "TaprootAnchorSweepSpend"
case TaprootHtlcOfferedTimeoutSecondLevel:
return "TaprootHtlcOfferedTimeoutSecondLevel"
case TaprootHtlcAcceptedSuccessSecondLevel:
return "TaprootHtlcAcceptedSuccessSecondLevel"
case TaprootHtlcSecondLevelRevoke:
return "TaprootHtlcSecondLevelRevoke"
case TaprootHtlcAcceptedRevoke:
return "TaprootHtlcAcceptedRevoke"
case TaprootHtlcOfferedRevoke:
return "TaprootHtlcOfferedRevoke"
case TaprootHtlcOfferedRemoteTimeout:
return "TaprootHtlcOfferedRemoteTimeout"
case TaprootHtlcLocalOfferedTimeout:
return "TaprootHtlcLocalOfferedTimeout"
case TaprootHtlcAcceptedRemoteSuccess:
return "TaprootHtlcAcceptedRemoteSuccess"
case TaprootHtlcAcceptedLocalSuccess:
return "TaprootHtlcAcceptedLocalSuccess"
case TaprootCommitmentRevoke:
return "TaprootCommitmentRevoke"
default:
return fmt.Sprintf("Unknown WitnessType: %v", uint32(wt))
}
}
// WitnessGenerator will return a WitnessGenerator function that an output uses
// to generate the witness and optionally the sigScript for a sweep
// transaction. The sigScript will be generated if the witness type warrants
// one for spending, such as the NestedWitnessKeyHash witness type.
//
// NOTE: This is part of the WitnessType interface.
func (wt StandardWitnessType) WitnessGenerator(signer Signer,
descriptor *SignDescriptor) WitnessGenerator {
return func(tx *wire.MsgTx, hc *txscript.TxSigHashes,
inputIndex int) (*Script, error) {
// TODO(roasbeef): copy the desc?
desc := descriptor
desc.SigHashes = hc
desc.InputIndex = inputIndex
switch wt {
case CommitmentTimeLock, LeaseCommitmentTimeLock:
witness, err := CommitSpendTimeout(signer, desc, tx)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case CommitmentToRemoteConfirmed, LeaseCommitmentToRemoteConfirmed:
witness, err := CommitSpendToRemoteConfirmed(
signer, desc, tx,
)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case CommitmentAnchor:
witness, err := CommitSpendAnchor(signer, desc, tx)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case CommitmentNoDelay:
witness, err := CommitSpendNoDelay(signer, desc, tx, false)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case CommitSpendNoDelayTweakless:
witness, err := CommitSpendNoDelay(signer, desc, tx, true)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case CommitmentRevoke:
witness, err := CommitSpendRevoke(signer, desc, tx)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case HtlcOfferedRevoke:
witness, err := ReceiverHtlcSpendRevoke(signer, desc, tx)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case HtlcAcceptedRevoke:
witness, err := SenderHtlcSpendRevoke(signer, desc, tx)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case HtlcOfferedTimeoutSecondLevel,
LeaseHtlcOfferedTimeoutSecondLevel,
HtlcAcceptedSuccessSecondLevel,
LeaseHtlcAcceptedSuccessSecondLevel:
witness, err := HtlcSecondLevelSpend(signer, desc, tx)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case HtlcOfferedRemoteTimeout:
// We pass in a value of -1 for the timeout, as we
// expect the caller to have already set the lock time
// value.
witness, err := ReceiverHtlcSpendTimeout(signer, desc, tx, -1)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case HtlcSecondLevelRevoke:
witness, err := HtlcSpendRevoke(signer, desc, tx)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case WitnessKeyHash:
fallthrough
case TaprootPubKeySpend:
fallthrough
case NestedWitnessKeyHash:
return signer.ComputeInputScript(tx, desc)
case TaprootLocalCommitSpend:
// Ensure that the sign desc has the proper sign method
// set, and a valid prev output fetcher.
desc.SignMethod = TaprootScriptSpendSignMethod
// The control block bytes must be set at this point.
if desc.ControlBlock == nil {
return nil, fmt.Errorf("control block must " +
"be set for taproot spend")
}
witness, err := TaprootCommitSpendSuccess(
signer, desc, tx, nil,
)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case TaprootRemoteCommitSpend:
// Ensure that the sign desc has the proper sign method
// set, and a valid prev output fetcher.
desc.SignMethod = TaprootScriptSpendSignMethod
// The control block bytes must be set at this point.
if desc.ControlBlock == nil {
return nil, fmt.Errorf("control block must " +
"be set for taproot spend")
}
witness, err := TaprootCommitRemoteSpend(
signer, desc, tx, nil,
)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case TaprootAnchorSweepSpend:
// Ensure that the sign desc has the proper sign method
// set, and a valid prev output fetcher.
desc.SignMethod = TaprootKeySpendSignMethod
// The tap tweak must be set at this point.
if desc.TapTweak == nil {
return nil, fmt.Errorf("tap tweak must be " +
"set for keyspend")
}
witness, err := TaprootAnchorSpend(
signer, desc, tx,
)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case TaprootHtlcOfferedTimeoutSecondLevel,
TaprootHtlcAcceptedSuccessSecondLevel:
// Ensure that the sign desc has the proper sign method
// set, and a valid prev output fetcher.
desc.SignMethod = TaprootScriptSpendSignMethod
// The control block bytes must be set at this point.
if desc.ControlBlock == nil {
return nil, fmt.Errorf("control block must " +
"be set for taproot spend")
}
witness, err := TaprootHtlcSpendSuccess(
signer, desc, tx, nil, nil,
)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case TaprootHtlcSecondLevelRevoke:
// Ensure that the sign desc has the proper sign method
// set, and a valid prev output fetcher.
desc.SignMethod = TaprootKeySpendSignMethod
// The tap tweak must be set at this point.
if desc.TapTweak == nil {
return nil, fmt.Errorf("tap tweak must be " +
"set for keyspend")
}
witness, err := TaprootHtlcSpendRevoke(
signer, desc, tx,
)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case TaprootHtlcOfferedRevoke:
// Ensure that the sign desc has the proper sign method
// set, and a valid prev output fetcher.
desc.SignMethod = TaprootKeySpendSignMethod
// The tap tweak must be set at this point.
if desc.TapTweak == nil {
return nil, fmt.Errorf("tap tweak must be " +
"set for keyspend")
}
witness, err := SenderHTLCScriptTaprootRevoke(
signer, desc, tx,
)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case TaprootHtlcAcceptedRevoke:
// Ensure that the sign desc has the proper sign method
// set, and a valid prev output fetcher.
desc.SignMethod = TaprootKeySpendSignMethod
// The tap tweak must be set at this point.
if desc.TapTweak == nil {
return nil, fmt.Errorf("tap tweak must be " +
"set for keyspend")
}
witness, err := ReceiverHTLCScriptTaprootRevoke(
signer, desc, tx,
)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case TaprootHtlcOfferedRemoteTimeout:
// Ensure that the sign desc has the proper sign method
// set, and a valid prev output fetcher.
desc.SignMethod = TaprootScriptSpendSignMethod
// The control block bytes must be set at this point.
if desc.ControlBlock == nil {
return nil, fmt.Errorf("control block " +
"must be set for taproot spend")
}
witness, err := ReceiverHTLCScriptTaprootTimeout(
signer, desc, tx, -1, nil, nil,
)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
case TaprootCommitmentRevoke:
// Ensure that the sign desc has the proper sign method
// set, and a valid prev output fetcher.
desc.SignMethod = TaprootScriptSpendSignMethod
// The control block bytes must be set at this point.
if desc.ControlBlock == nil {
return nil, fmt.Errorf("control block " +
"must be set for taproot spend")
}
witness, err := TaprootCommitSpendRevoke(
signer, desc, tx, nil,
)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
default:
return nil, fmt.Errorf("unknown witness type: %v", wt)
}
}
}
// SizeUpperBound returns the maximum length of the witness of this witness
// type if it would be included in a tx. We also return if the output itself is
// a nested p2sh output, if so then we need to take into account the extra
// sigScript data size.
//
// NOTE: This is part of the WitnessType interface.
func (wt StandardWitnessType) SizeUpperBound() (int, bool, error) {
switch wt {
// Outputs on a remote commitment transaction that pay directly to us.
case CommitSpendNoDelayTweakless:
fallthrough
case WitnessKeyHash:
fallthrough
case CommitmentNoDelay:
return P2WKHWitnessSize, false, nil
// Outputs on a past commitment transaction that pay directly
// to us.
case CommitmentTimeLock:
return ToLocalTimeoutWitnessSize, false, nil
case LeaseCommitmentTimeLock:
size := ToLocalTimeoutWitnessSize +
LeaseWitnessScriptSizeOverhead
return size, false, nil
// 1 CSV time locked output to us on remote commitment.
case CommitmentToRemoteConfirmed:
return ToRemoteConfirmedWitnessSize, false, nil
case LeaseCommitmentToRemoteConfirmed:
size := ToRemoteConfirmedWitnessSize +
LeaseWitnessScriptSizeOverhead
return size, false, nil
// Anchor output on the commitment transaction.
case CommitmentAnchor:
return AnchorWitnessSize, false, nil
// Outgoing second layer HTLC's that have confirmed within the
// chain, and the output they produced is now mature enough to
// sweep.
case HtlcOfferedTimeoutSecondLevel:
return ToLocalTimeoutWitnessSize, false, nil
case LeaseHtlcOfferedTimeoutSecondLevel:
size := ToLocalTimeoutWitnessSize +
LeaseWitnessScriptSizeOverhead
return size, false, nil
// Input to the outgoing HTLC second layer timeout transaction.
case HtlcOfferedTimeoutSecondLevelInputConfirmed:
return OfferedHtlcTimeoutWitnessSizeConfirmed, false, nil
// Incoming second layer HTLC's that have confirmed within the
// chain, and the output they produced is now mature enough to
// sweep.
case HtlcAcceptedSuccessSecondLevel:
return ToLocalTimeoutWitnessSize, false, nil
case LeaseHtlcAcceptedSuccessSecondLevel:
size := ToLocalTimeoutWitnessSize +
LeaseWitnessScriptSizeOverhead
return size, false, nil
// Input to the incoming second-layer HTLC success transaction.
case HtlcAcceptedSuccessSecondLevelInputConfirmed:
return AcceptedHtlcSuccessWitnessSizeConfirmed, false, nil
// An HTLC on the commitment transaction of the remote party,
// that has had its absolute timelock expire.
case HtlcOfferedRemoteTimeout:
return AcceptedHtlcTimeoutWitnessSize, false, nil
// An HTLC on the commitment transaction of the remote party,
// that can be swept with the preimage.
case HtlcAcceptedRemoteSuccess:
return OfferedHtlcSuccessWitnessSize, false, nil
// A nested P2SH input that has a p2wkh witness script. We'll mark this
// as nested P2SH so the caller can estimate the weight properly
// including the sigScript.
case NestedWitnessKeyHash:
return P2WKHWitnessSize, true, nil
// The revocation output on a revoked commitment transaction.
case CommitmentRevoke:
return ToLocalPenaltyWitnessSize, false, nil
// The revocation output on a revoked HTLC that we offered to the remote
// party.
case HtlcOfferedRevoke:
return OfferedHtlcPenaltyWitnessSize, false, nil
// The revocation output on a revoked HTLC that was sent to us.
case HtlcAcceptedRevoke:
return AcceptedHtlcPenaltyWitnessSize, false, nil
// The revocation output of a second level output of an HTLC.
case HtlcSecondLevelRevoke:
return ToLocalPenaltyWitnessSize, false, nil
case TaprootPubKeySpend:
return TaprootKeyPathCustomSighashWitnessSize, false, nil
// Sweeping a self output after a delay for taproot channels.
case TaprootLocalCommitSpend:
return TaprootToLocalWitnessSize, false, nil
// Sweeping a self output after the remote party fro ce closes. Must
// wait 1 CSV.
case TaprootRemoteCommitSpend:
return TaprootToRemoteWitnessSize, false, nil
// Sweeping our anchor output with a key spend witness.
case TaprootAnchorSweepSpend:
return TaprootAnchorWitnessSize, false, nil
case TaprootHtlcOfferedTimeoutSecondLevel,
TaprootHtlcAcceptedSuccessSecondLevel:
return TaprootSecondLevelHtlcWitnessSize, false, nil
case TaprootHtlcSecondLevelRevoke:
return TaprootSecondLevelRevokeWitnessSize, false, nil
case TaprootHtlcAcceptedRevoke:
return TaprootAcceptedRevokeWitnessSize, false, nil
case TaprootHtlcOfferedRevoke:
return TaprootOfferedRevokeWitnessSize, false, nil
case TaprootHtlcOfferedRemoteTimeout:
return TaprootHtlcOfferedRemoteTimeoutWitnessSize, false, nil
case TaprootHtlcLocalOfferedTimeout:
return TaprootOfferedLocalTimeoutWitnessSize, false, nil
case TaprootHtlcAcceptedRemoteSuccess:
return TaprootHtlcAcceptedRemoteSuccessWitnessSize, false, nil
case TaprootHtlcAcceptedLocalSuccess:
return TaprootHtlcAcceptedLocalSuccessWitnessSize, false, nil
case TaprootCommitmentRevoke:
return TaprootToLocalRevokeWitnessSize, false, nil
}
return 0, false, fmt.Errorf("unexpected witness type: %v", wt)
}
// AddWeightEstimation adds the estimated size of the witness in bytes to the
// given weight estimator.
//
// NOTE: This is part of the WitnessType interface.
func (wt StandardWitnessType) AddWeightEstimation(e *TxWeightEstimator) error {
// For fee estimation purposes, we'll now attempt to obtain an
// upper bound on the weight this input will add when fully
// populated.
size, isNestedP2SH, err := wt.SizeUpperBound()
if err != nil {
return err
}
// If this is a nested P2SH input, then we'll need to factor in
// the additional data push within the sigScript.
if isNestedP2SH {
e.AddNestedP2WSHInput(size)
} else {
e.AddWitnessInput(size)
}
return nil
}