mirror of
https://github.com/muun/recovery.git
synced 2025-11-10 22:10:14 -05:00
Release v0.3.0
This commit is contained in:
200
vendor/github.com/lightningnetwork/lnd/input/input.go
generated
vendored
Normal file
200
vendor/github.com/lightningnetwork/lnd/input/input.go
generated
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
)
|
||||
|
||||
// Input represents an abstract UTXO which is to be spent using a sweeping
|
||||
// transaction. The method provided give the caller all information needed to
|
||||
// construct a valid input within a sweeping transaction to sweep this
|
||||
// lingering UTXO.
|
||||
type Input interface {
|
||||
// Outpoint returns the reference to the output being spent, used to
|
||||
// construct the corresponding transaction input.
|
||||
OutPoint() *wire.OutPoint
|
||||
|
||||
// WitnessType returns an enum specifying the type of witness that must
|
||||
// be generated in order to spend this output.
|
||||
WitnessType() WitnessType
|
||||
|
||||
// SignDesc returns a reference to a spendable output's sign
|
||||
// descriptor, which is used during signing to compute a valid witness
|
||||
// that spends this output.
|
||||
SignDesc() *SignDescriptor
|
||||
|
||||
// CraftInputScript returns a valid set of input scripts allowing this
|
||||
// output to be spent. The returns input scripts should target the
|
||||
// input at location txIndex within the passed transaction. The input
|
||||
// scripts generated by this method support spending p2wkh, p2wsh, and
|
||||
// also nested p2sh outputs.
|
||||
CraftInputScript(signer Signer, txn *wire.MsgTx,
|
||||
hashCache *txscript.TxSigHashes,
|
||||
txinIdx int) (*Script, error)
|
||||
|
||||
// BlocksToMaturity returns the relative timelock, as a number of
|
||||
// blocks, that must be built on top of the confirmation height before
|
||||
// the output can be spent. For non-CSV locked inputs this is always
|
||||
// zero.
|
||||
BlocksToMaturity() uint32
|
||||
|
||||
// HeightHint returns the minimum height at which a confirmed spending
|
||||
// tx can occur.
|
||||
HeightHint() uint32
|
||||
}
|
||||
|
||||
type inputKit struct {
|
||||
outpoint wire.OutPoint
|
||||
witnessType WitnessType
|
||||
signDesc SignDescriptor
|
||||
heightHint uint32
|
||||
blockToMaturity uint32
|
||||
}
|
||||
|
||||
// OutPoint returns the breached output's identifier that is to be included as
|
||||
// a transaction input.
|
||||
func (i *inputKit) OutPoint() *wire.OutPoint {
|
||||
return &i.outpoint
|
||||
}
|
||||
|
||||
// WitnessType returns the type of witness that must be generated to spend the
|
||||
// breached output.
|
||||
func (i *inputKit) WitnessType() WitnessType {
|
||||
return i.witnessType
|
||||
}
|
||||
|
||||
// SignDesc returns the breached output's SignDescriptor, which is used during
|
||||
// signing to compute the witness.
|
||||
func (i *inputKit) SignDesc() *SignDescriptor {
|
||||
return &i.signDesc
|
||||
}
|
||||
|
||||
// HeightHint returns the minimum height at which a confirmed spending
|
||||
// tx can occur.
|
||||
func (i *inputKit) HeightHint() uint32 {
|
||||
return i.heightHint
|
||||
}
|
||||
|
||||
// BlocksToMaturity returns the relative timelock, as a number of blocks, that
|
||||
// must be built on top of the confirmation height before the output can be
|
||||
// spent. For non-CSV locked inputs this is always zero.
|
||||
func (i *inputKit) BlocksToMaturity() uint32 {
|
||||
return i.blockToMaturity
|
||||
}
|
||||
|
||||
// BaseInput contains all the information needed to sweep a basic output
|
||||
// (CSV/CLTV/no time lock)
|
||||
type BaseInput struct {
|
||||
inputKit
|
||||
}
|
||||
|
||||
// MakeBaseInput assembles a new BaseInput that can be used to construct a
|
||||
// sweep transaction.
|
||||
func MakeBaseInput(outpoint *wire.OutPoint, witnessType WitnessType,
|
||||
signDescriptor *SignDescriptor, heightHint uint32) BaseInput {
|
||||
|
||||
return BaseInput{
|
||||
inputKit{
|
||||
outpoint: *outpoint,
|
||||
witnessType: witnessType,
|
||||
signDesc: *signDescriptor,
|
||||
heightHint: heightHint,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NewBaseInput allocates and assembles a new *BaseInput that can be used to
|
||||
// construct a sweep transaction.
|
||||
func NewBaseInput(outpoint *wire.OutPoint, witnessType WitnessType,
|
||||
signDescriptor *SignDescriptor, heightHint uint32) *BaseInput {
|
||||
|
||||
input := MakeBaseInput(
|
||||
outpoint, witnessType, signDescriptor, heightHint,
|
||||
)
|
||||
|
||||
return &input
|
||||
}
|
||||
|
||||
// NewCsvInput assembles a new csv-locked input that can be used to
|
||||
// construct a sweep transaction.
|
||||
func NewCsvInput(outpoint *wire.OutPoint, witnessType WitnessType,
|
||||
signDescriptor *SignDescriptor, heightHint uint32,
|
||||
blockToMaturity uint32) *BaseInput {
|
||||
|
||||
return &BaseInput{
|
||||
inputKit{
|
||||
outpoint: *outpoint,
|
||||
witnessType: witnessType,
|
||||
signDesc: *signDescriptor,
|
||||
heightHint: heightHint,
|
||||
blockToMaturity: blockToMaturity,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// CraftInputScript returns a valid set of input scripts allowing this output
|
||||
// to be spent. The returned input scripts should target the input at location
|
||||
// txIndex within the passed transaction. The input scripts generated by this
|
||||
// method support spending p2wkh, p2wsh, and also nested p2sh outputs.
|
||||
func (bi *BaseInput) CraftInputScript(signer Signer, txn *wire.MsgTx,
|
||||
hashCache *txscript.TxSigHashes, txinIdx int) (*Script, error) {
|
||||
|
||||
witnessFunc := bi.witnessType.WitnessGenerator(signer, bi.SignDesc())
|
||||
|
||||
return witnessFunc(txn, hashCache, txinIdx)
|
||||
}
|
||||
|
||||
// HtlcSucceedInput constitutes a sweep input that needs a pre-image. The input
|
||||
// is expected to reside on the commitment tx of the remote party and should
|
||||
// not be a second level tx output.
|
||||
type HtlcSucceedInput struct {
|
||||
inputKit
|
||||
|
||||
preimage []byte
|
||||
}
|
||||
|
||||
// MakeHtlcSucceedInput assembles a new redeem input that can be used to
|
||||
// construct a sweep transaction.
|
||||
func MakeHtlcSucceedInput(outpoint *wire.OutPoint,
|
||||
signDescriptor *SignDescriptor, preimage []byte, heightHint,
|
||||
blocksToMaturity uint32) HtlcSucceedInput {
|
||||
|
||||
return HtlcSucceedInput{
|
||||
inputKit: inputKit{
|
||||
outpoint: *outpoint,
|
||||
witnessType: HtlcAcceptedRemoteSuccess,
|
||||
signDesc: *signDescriptor,
|
||||
heightHint: heightHint,
|
||||
blockToMaturity: blocksToMaturity,
|
||||
},
|
||||
preimage: preimage,
|
||||
}
|
||||
}
|
||||
|
||||
// CraftInputScript returns a valid set of input scripts allowing this output
|
||||
// to be spent. The returns input scripts should target the input at location
|
||||
// txIndex within the passed transaction. The input scripts generated by this
|
||||
// method support spending p2wkh, p2wsh, and also nested p2sh outputs.
|
||||
func (h *HtlcSucceedInput) CraftInputScript(signer Signer, txn *wire.MsgTx,
|
||||
hashCache *txscript.TxSigHashes, txinIdx int) (*Script, error) {
|
||||
|
||||
desc := h.signDesc
|
||||
desc.SigHashes = hashCache
|
||||
desc.InputIndex = txinIdx
|
||||
|
||||
witness, err := SenderHtlcSpendRedeem(
|
||||
signer, &desc, txn, h.preimage,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Script{
|
||||
Witness: witness,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Compile-time constraints to ensure each input struct implement the Input
|
||||
// interface.
|
||||
var _ Input = (*BaseInput)(nil)
|
||||
var _ Input = (*HtlcSucceedInput)(nil)
|
||||
1298
vendor/github.com/lightningnetwork/lnd/input/script_utils.go
generated
vendored
Normal file
1298
vendor/github.com/lightningnetwork/lnd/input/script_utils.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
226
vendor/github.com/lightningnetwork/lnd/input/signdescriptor.go
generated
vendored
Normal file
226
vendor/github.com/lightningnetwork/lnd/input/signdescriptor.go
generated
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrTweakOverdose signals a SignDescriptor is invalid because both of its
|
||||
// SingleTweak and DoubleTweak are non-nil.
|
||||
ErrTweakOverdose = errors.New("sign descriptor should only have one tweak")
|
||||
)
|
||||
|
||||
// SignDescriptor houses the necessary information required to successfully
|
||||
// sign a given segwit output. This struct is used by the Signer interface in
|
||||
// order to gain access to critical data needed to generate a valid signature.
|
||||
type SignDescriptor struct {
|
||||
// KeyDesc is a descriptor that precisely describes *which* key to use
|
||||
// for signing. This may provide the raw public key directly, or
|
||||
// require the Signer to re-derive the key according to the populated
|
||||
// derivation path.
|
||||
KeyDesc keychain.KeyDescriptor
|
||||
|
||||
// SingleTweak is a scalar value that will be added to the private key
|
||||
// corresponding to the above public key to obtain the private key to
|
||||
// be used to sign this input. This value is typically derived via the
|
||||
// following computation:
|
||||
//
|
||||
// * derivedKey = privkey + sha256(perCommitmentPoint || pubKey) mod N
|
||||
//
|
||||
// NOTE: If this value is nil, then the input can be signed using only
|
||||
// the above public key. Either a SingleTweak should be set or a
|
||||
// DoubleTweak, not both.
|
||||
SingleTweak []byte
|
||||
|
||||
// DoubleTweak is a private key that will be used in combination with
|
||||
// its corresponding private key to derive the private key that is to
|
||||
// be used to sign the target input. Within the Lightning protocol,
|
||||
// this value is typically the commitment secret from a previously
|
||||
// revoked commitment transaction. This value is in combination with
|
||||
// two hash values, and the original private key to derive the private
|
||||
// key to be used when signing.
|
||||
//
|
||||
// * k = (privKey*sha256(pubKey || tweakPub) +
|
||||
// tweakPriv*sha256(tweakPub || pubKey)) mod N
|
||||
//
|
||||
// NOTE: If this value is nil, then the input can be signed using only
|
||||
// the above public key. Either a SingleTweak should be set or a
|
||||
// DoubleTweak, not both.
|
||||
DoubleTweak *btcec.PrivateKey
|
||||
|
||||
// WitnessScript is the full script required to properly redeem the
|
||||
// output. This field should be set to the full script if a p2wsh
|
||||
// output is being signed. For p2wkh it should be set to the hashed
|
||||
// script (PkScript).
|
||||
WitnessScript []byte
|
||||
|
||||
// Output is the target output which should be signed. The PkScript and
|
||||
// Value fields within the output should be properly populated,
|
||||
// otherwise an invalid signature may be generated.
|
||||
Output *wire.TxOut
|
||||
|
||||
// HashType is the target sighash type that should be used when
|
||||
// generating the final sighash, and signature.
|
||||
HashType txscript.SigHashType
|
||||
|
||||
// SigHashes is the pre-computed sighash midstate to be used when
|
||||
// generating the final sighash for signing.
|
||||
SigHashes *txscript.TxSigHashes
|
||||
|
||||
// InputIndex is the target input within the transaction that should be
|
||||
// signed.
|
||||
InputIndex int
|
||||
}
|
||||
|
||||
// WriteSignDescriptor serializes a SignDescriptor struct into the passed
|
||||
// io.Writer stream.
|
||||
//
|
||||
// NOTE: We assume the SigHashes and InputIndex fields haven't been assigned
|
||||
// yet, since that is usually done just before broadcast by the witness
|
||||
// generator.
|
||||
func WriteSignDescriptor(w io.Writer, sd *SignDescriptor) error {
|
||||
err := binary.Write(w, binary.BigEndian, sd.KeyDesc.Family)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, sd.KeyDesc.Index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = binary.Write(w, binary.BigEndian, sd.KeyDesc.PubKey != nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if sd.KeyDesc.PubKey != nil {
|
||||
serializedPubKey := sd.KeyDesc.PubKey.SerializeCompressed()
|
||||
if err := wire.WriteVarBytes(w, 0, serializedPubKey); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := wire.WriteVarBytes(w, 0, sd.SingleTweak); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var doubleTweakBytes []byte
|
||||
if sd.DoubleTweak != nil {
|
||||
doubleTweakBytes = sd.DoubleTweak.Serialize()
|
||||
}
|
||||
if err := wire.WriteVarBytes(w, 0, doubleTweakBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := wire.WriteVarBytes(w, 0, sd.WitnessScript); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeTxOut(w, sd.Output); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var scratch [4]byte
|
||||
binary.BigEndian.PutUint32(scratch[:], uint32(sd.HashType))
|
||||
if _, err := w.Write(scratch[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadSignDescriptor deserializes a SignDescriptor struct from the passed
|
||||
// io.Reader stream.
|
||||
func ReadSignDescriptor(r io.Reader, sd *SignDescriptor) error {
|
||||
err := binary.Read(r, binary.BigEndian, &sd.KeyDesc.Family)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &sd.KeyDesc.Index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var hasKey bool
|
||||
err = binary.Read(r, binary.BigEndian, &hasKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if hasKey {
|
||||
pubKeyBytes, err := wire.ReadVarBytes(r, 0, 34, "pubkey")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sd.KeyDesc.PubKey, err = btcec.ParsePubKey(
|
||||
pubKeyBytes, btcec.S256(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
singleTweak, err := wire.ReadVarBytes(r, 0, 32, "singleTweak")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Serializing a SignDescriptor with a nil-valued SingleTweak results
|
||||
// in deserializing a zero-length slice. Since a nil-valued SingleTweak
|
||||
// has special meaning and a zero-length slice for a SingleTweak is
|
||||
// invalid, we can use the zero-length slice as the flag for a
|
||||
// nil-valued SingleTweak.
|
||||
if len(singleTweak) == 0 {
|
||||
sd.SingleTweak = nil
|
||||
} else {
|
||||
sd.SingleTweak = singleTweak
|
||||
}
|
||||
|
||||
doubleTweakBytes, err := wire.ReadVarBytes(r, 0, 32, "doubleTweak")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Serializing a SignDescriptor with a nil-valued DoubleTweak results
|
||||
// in deserializing a zero-length slice. Since a nil-valued DoubleTweak
|
||||
// has special meaning and a zero-length slice for a DoubleTweak is
|
||||
// invalid, we can use the zero-length slice as the flag for a
|
||||
// nil-valued DoubleTweak.
|
||||
if len(doubleTweakBytes) == 0 {
|
||||
sd.DoubleTweak = nil
|
||||
} else {
|
||||
sd.DoubleTweak, _ = btcec.PrivKeyFromBytes(btcec.S256(), doubleTweakBytes)
|
||||
}
|
||||
|
||||
// Only one tweak should ever be set, fail if both are present.
|
||||
if sd.SingleTweak != nil && sd.DoubleTweak != nil {
|
||||
return ErrTweakOverdose
|
||||
}
|
||||
|
||||
witnessScript, err := wire.ReadVarBytes(r, 0, 500, "witnessScript")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sd.WitnessScript = witnessScript
|
||||
|
||||
txOut := &wire.TxOut{}
|
||||
if err := readTxOut(r, txOut); err != nil {
|
||||
return err
|
||||
}
|
||||
sd.Output = txOut
|
||||
|
||||
var hashType [4]byte
|
||||
if _, err := io.ReadFull(r, hashType[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
sd.HashType = txscript.SigHashType(binary.BigEndian.Uint32(hashType[:]))
|
||||
|
||||
return nil
|
||||
}
|
||||
42
vendor/github.com/lightningnetwork/lnd/input/signer.go
generated
vendored
Normal file
42
vendor/github.com/lightningnetwork/lnd/input/signer.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
)
|
||||
|
||||
// Signer represents an abstract object capable of generating raw signatures as
|
||||
// well as full complete input scripts given a valid SignDescriptor and
|
||||
// transaction. This interface fully abstracts away signing paving the way for
|
||||
// Signer implementations such as hardware wallets, hardware tokens, HSM's, or
|
||||
// simply a regular wallet.
|
||||
type Signer interface {
|
||||
// SignOutputRaw generates a signature for the passed transaction
|
||||
// according to the data within the passed SignDescriptor.
|
||||
//
|
||||
// NOTE: The resulting signature should be void of a sighash byte.
|
||||
SignOutputRaw(tx *wire.MsgTx,
|
||||
signDesc *SignDescriptor) (Signature, error)
|
||||
|
||||
// ComputeInputScript generates a complete InputIndex for the passed
|
||||
// transaction with the signature as defined within the passed
|
||||
// SignDescriptor. This method should be capable of generating the
|
||||
// proper input script for both regular p2wkh output and p2wkh outputs
|
||||
// nested within a regular p2sh output.
|
||||
//
|
||||
// NOTE: This method will ignore any tweak parameters set within the
|
||||
// passed SignDescriptor as it assumes a set of typical script
|
||||
// templates (p2wkh, np2wkh, etc).
|
||||
ComputeInputScript(tx *wire.MsgTx, signDesc *SignDescriptor) (*Script, error)
|
||||
}
|
||||
|
||||
// Script represents any script inputs required to redeem a previous
|
||||
// output. This struct is used rather than just a witness, or scripSig in order
|
||||
// to accommodate nested p2sh which utilizes both types of input scripts.
|
||||
type Script struct {
|
||||
// Witness is the full witness stack required to unlock this output.
|
||||
Witness wire.TxWitness
|
||||
|
||||
// SigScript will only be populated if this is an input script sweeping
|
||||
// a nested p2sh output.
|
||||
SigScript []byte
|
||||
}
|
||||
588
vendor/github.com/lightningnetwork/lnd/input/size.go
generated
vendored
Normal file
588
vendor/github.com/lightningnetwork/lnd/input/size.go
generated
vendored
Normal file
@@ -0,0 +1,588 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"github.com/btcsuite/btcd/blockchain"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
)
|
||||
|
||||
const (
|
||||
// witnessScaleFactor determines the level of "discount" witness data
|
||||
// receives compared to "base" data. A scale factor of 4, denotes that
|
||||
// witness data is 1/4 as cheap as regular non-witness data. Value copied
|
||||
// here for convenience.
|
||||
witnessScaleFactor = blockchain.WitnessScaleFactor
|
||||
|
||||
// The weight(weight), which is different from the !size! (see BIP-141),
|
||||
// is calculated as:
|
||||
// Weight = 4 * BaseSize + WitnessSize (weight).
|
||||
// BaseSize - size of the transaction without witness data (bytes).
|
||||
// WitnessSize - witness size (bytes).
|
||||
// Weight - the metric for determining the weight of the transaction.
|
||||
|
||||
// P2WPKHSize 22 bytes
|
||||
// - OP_0: 1 byte
|
||||
// - OP_DATA: 1 byte (PublicKeyHASH160 length)
|
||||
// - PublicKeyHASH160: 20 bytes
|
||||
P2WPKHSize = 1 + 1 + 20
|
||||
|
||||
// NestedP2WPKHSize 23 bytes
|
||||
// - OP_DATA: 1 byte (P2WPKHSize)
|
||||
// - P2WPKHWitnessProgram: 22 bytes
|
||||
NestedP2WPKHSize = 1 + P2WPKHSize
|
||||
|
||||
// P2WSHSize 34 bytes
|
||||
// - OP_0: 1 byte
|
||||
// - OP_DATA: 1 byte (WitnessScriptSHA256 length)
|
||||
// - WitnessScriptSHA256: 32 bytes
|
||||
P2WSHSize = 1 + 1 + 32
|
||||
|
||||
// NestedP2WSHSize 35 bytes
|
||||
// - OP_DATA: 1 byte (P2WSHSize)
|
||||
// - P2WSHWitnessProgram: 34 bytes
|
||||
NestedP2WSHSize = 1 + P2WSHSize
|
||||
|
||||
// P2PKHOutputSize 34 bytes
|
||||
// - value: 8 bytes
|
||||
// - var_int: 1 byte (pkscript_length)
|
||||
// - pkscript (p2pkh): 25 bytes
|
||||
P2PKHOutputSize = 8 + 1 + 25
|
||||
|
||||
// P2WKHOutputSize 31 bytes
|
||||
// - value: 8 bytes
|
||||
// - var_int: 1 byte (pkscript_length)
|
||||
// - pkscript (p2wpkh): 22 bytes
|
||||
P2WKHOutputSize = 8 + 1 + P2WPKHSize
|
||||
|
||||
// P2WSHOutputSize 43 bytes
|
||||
// - value: 8 bytes
|
||||
// - var_int: 1 byte (pkscript_length)
|
||||
// - pkscript (p2wsh): 34 bytes
|
||||
P2WSHOutputSize = 8 + 1 + P2WSHSize
|
||||
|
||||
// P2SHOutputSize 32 bytes
|
||||
// - value: 8 bytes
|
||||
// - var_int: 1 byte (pkscript_length)
|
||||
// - pkscript (p2sh): 23 bytes
|
||||
P2SHOutputSize = 8 + 1 + 23
|
||||
|
||||
// P2PKHScriptSigSize 108 bytes
|
||||
// - OP_DATA: 1 byte (signature length)
|
||||
// - signature
|
||||
// - OP_DATA: 1 byte (pubkey length)
|
||||
// - pubkey
|
||||
P2PKHScriptSigSize = 1 + 73 + 1 + 33
|
||||
|
||||
// P2WKHWitnessSize 109 bytes
|
||||
// - number_of_witness_elements: 1 byte
|
||||
// - signature_length: 1 byte
|
||||
// - signature
|
||||
// - pubkey_length: 1 byte
|
||||
// - pubkey
|
||||
P2WKHWitnessSize = 1 + 1 + 73 + 1 + 33
|
||||
|
||||
// MultiSigSize 71 bytes
|
||||
// - OP_2: 1 byte
|
||||
// - OP_DATA: 1 byte (pubKeyAlice length)
|
||||
// - pubKeyAlice: 33 bytes
|
||||
// - OP_DATA: 1 byte (pubKeyBob length)
|
||||
// - pubKeyBob: 33 bytes
|
||||
// - OP_2: 1 byte
|
||||
// - OP_CHECKMULTISIG: 1 byte
|
||||
MultiSigSize = 1 + 1 + 33 + 1 + 33 + 1 + 1
|
||||
|
||||
// MultiSigWitnessSize 222 bytes
|
||||
// - NumberOfWitnessElements: 1 byte
|
||||
// - NilLength: 1 byte
|
||||
// - sigAliceLength: 1 byte
|
||||
// - sigAlice: 73 bytes
|
||||
// - sigBobLength: 1 byte
|
||||
// - sigBob: 73 bytes
|
||||
// - WitnessScriptLength: 1 byte
|
||||
// - WitnessScript (MultiSig)
|
||||
MultiSigWitnessSize = 1 + 1 + 1 + 73 + 1 + 73 + 1 + MultiSigSize
|
||||
|
||||
// InputSize 41 bytes
|
||||
// - PreviousOutPoint:
|
||||
// - Hash: 32 bytes
|
||||
// - Index: 4 bytes
|
||||
// - OP_DATA: 1 byte (ScriptSigLength)
|
||||
// - ScriptSig: 0 bytes
|
||||
// - Witness <---- we use "Witness" instead of "ScriptSig" for
|
||||
// transaction validation, but "Witness" is stored
|
||||
// separately and weight for it size is smaller. So
|
||||
// we separate the calculation of ordinary data
|
||||
// from witness data.
|
||||
// - Sequence: 4 bytes
|
||||
InputSize = 32 + 4 + 1 + 4
|
||||
|
||||
// FundingInputSize represents the size of an input to a funding
|
||||
// transaction, and is equivalent to the size of a standard segwit input
|
||||
// as calculated above.
|
||||
FundingInputSize = InputSize
|
||||
|
||||
// CommitmentDelayOutput 43 bytes
|
||||
// - Value: 8 bytes
|
||||
// - VarInt: 1 byte (PkScript length)
|
||||
// - PkScript (P2WSH)
|
||||
CommitmentDelayOutput = 8 + 1 + P2WSHSize
|
||||
|
||||
// CommitmentKeyHashOutput 31 bytes
|
||||
// - Value: 8 bytes
|
||||
// - VarInt: 1 byte (PkScript length)
|
||||
// - PkScript (P2WPKH)
|
||||
CommitmentKeyHashOutput = 8 + 1 + P2WPKHSize
|
||||
|
||||
// CommitmentAnchorOutput 43 bytes
|
||||
// - Value: 8 bytes
|
||||
// - VarInt: 1 byte (PkScript length)
|
||||
// - PkScript (P2WSH)
|
||||
CommitmentAnchorOutput = 8 + 1 + P2WSHSize
|
||||
|
||||
// HTLCSize 43 bytes
|
||||
// - Value: 8 bytes
|
||||
// - VarInt: 1 byte (PkScript length)
|
||||
// - PkScript (PW2SH)
|
||||
HTLCSize = 8 + 1 + P2WSHSize
|
||||
|
||||
// WitnessHeaderSize 2 bytes
|
||||
// - Flag: 1 byte
|
||||
// - Marker: 1 byte
|
||||
WitnessHeaderSize = 1 + 1
|
||||
|
||||
// BaseTxSize 8 bytes
|
||||
// - Version: 4 bytes
|
||||
// - LockTime: 4 bytes
|
||||
BaseTxSize = 4 + 4
|
||||
|
||||
// BaseCommitmentTxSize 125 + 43 * num-htlc-outputs bytes
|
||||
// - Version: 4 bytes
|
||||
// - WitnessHeader <---- part of the witness data
|
||||
// - CountTxIn: 1 byte
|
||||
// - TxIn: 41 bytes
|
||||
// FundingInput
|
||||
// - CountTxOut: 1 byte
|
||||
// - TxOut: 74 + 43 * num-htlc-outputs bytes
|
||||
// OutputPayingToThem,
|
||||
// OutputPayingToUs,
|
||||
// ....HTLCOutputs...
|
||||
// - LockTime: 4 bytes
|
||||
BaseCommitmentTxSize = 4 + 1 + FundingInputSize + 1 +
|
||||
CommitmentDelayOutput + CommitmentKeyHashOutput + 4
|
||||
|
||||
// BaseCommitmentTxWeight 500 weight
|
||||
BaseCommitmentTxWeight = witnessScaleFactor * BaseCommitmentTxSize
|
||||
|
||||
// WitnessCommitmentTxWeight 224 weight
|
||||
WitnessCommitmentTxWeight = WitnessHeaderSize + MultiSigWitnessSize
|
||||
|
||||
// BaseAnchorCommitmentTxSize 225 + 43 * num-htlc-outputs bytes
|
||||
// - Version: 4 bytes
|
||||
// - WitnessHeader <---- part of the witness data
|
||||
// - CountTxIn: 1 byte
|
||||
// - TxIn: 41 bytes
|
||||
// FundingInput
|
||||
// - CountTxOut: 3 byte
|
||||
// - TxOut: 4*43 + 43 * num-htlc-outputs bytes
|
||||
// OutputPayingToThem,
|
||||
// OutputPayingToUs,
|
||||
// AnchorPayingToThem,
|
||||
// AnchorPayingToUs,
|
||||
// ....HTLCOutputs...
|
||||
// - LockTime: 4 bytes
|
||||
BaseAnchorCommitmentTxSize = 4 + 1 + FundingInputSize + 3 +
|
||||
2*CommitmentDelayOutput + 2*CommitmentAnchorOutput + 4
|
||||
|
||||
// BaseAnchorCommitmentTxWeight 900 weight
|
||||
BaseAnchorCommitmentTxWeight = witnessScaleFactor * BaseAnchorCommitmentTxSize
|
||||
|
||||
// CommitWeight 724 weight
|
||||
CommitWeight = BaseCommitmentTxWeight + WitnessCommitmentTxWeight
|
||||
|
||||
// AnchorCommitWeight 1124 weight
|
||||
AnchorCommitWeight = BaseAnchorCommitmentTxWeight + WitnessCommitmentTxWeight
|
||||
|
||||
// HTLCWeight 172 weight
|
||||
HTLCWeight = witnessScaleFactor * HTLCSize
|
||||
|
||||
// HtlcTimeoutWeight is the weight of the HTLC timeout transaction
|
||||
// which will transition an outgoing HTLC to the delay-and-claim state.
|
||||
HtlcTimeoutWeight = 663
|
||||
|
||||
// HtlcSuccessWeight is the weight of the HTLC success transaction
|
||||
// which will transition an incoming HTLC to the delay-and-claim state.
|
||||
HtlcSuccessWeight = 703
|
||||
|
||||
// HtlcConfirmedScriptOverhead is the extra length of an HTLC script
|
||||
// that requires confirmation before it can be spent. These extra bytes
|
||||
// is a result of the extra CSV check.
|
||||
HtlcConfirmedScriptOverhead = 3
|
||||
|
||||
// HtlcTimeoutWeightConfirmed is the weight of the HTLC timeout
|
||||
// transaction which will transition an outgoing HTLC to the
|
||||
// delay-and-claim state, for the confirmed HTLC outputs. It is 3 bytes
|
||||
// larger because of the additional CSV check in the input script.
|
||||
HtlcTimeoutWeightConfirmed = HtlcTimeoutWeight + HtlcConfirmedScriptOverhead
|
||||
|
||||
// HtlcSuccessWeightCOnfirmed is the weight of the HTLC success
|
||||
// transaction which will transition an incoming HTLC to the
|
||||
// delay-and-claim state, for the confirmed HTLC outputs. It is 3 bytes
|
||||
// larger because of the cdditional CSV check in the input script.
|
||||
HtlcSuccessWeightConfirmed = HtlcSuccessWeight + HtlcConfirmedScriptOverhead
|
||||
|
||||
// MaxHTLCNumber is the maximum number HTLCs which can be included in a
|
||||
// commitment transaction. This limit was chosen such that, in the case
|
||||
// of a contract breach, the punishment transaction is able to sweep
|
||||
// all the HTLC's yet still remain below the widely used standard
|
||||
// weight limits.
|
||||
MaxHTLCNumber = 966
|
||||
|
||||
// ToLocalScriptSize 79 bytes
|
||||
// - OP_IF: 1 byte
|
||||
// - OP_DATA: 1 byte
|
||||
// - revoke_key: 33 bytes
|
||||
// - OP_ELSE: 1 byte
|
||||
// - OP_DATA: 1 byte
|
||||
// - csv_delay: 4 bytes
|
||||
// - OP_CHECKSEQUENCEVERIFY: 1 byte
|
||||
// - OP_DROP: 1 byte
|
||||
// - OP_DATA: 1 byte
|
||||
// - delay_key: 33 bytes
|
||||
// - OP_ENDIF: 1 byte
|
||||
// - OP_CHECKSIG: 1 byte
|
||||
ToLocalScriptSize = 1 + 1 + 33 + 1 + 1 + 4 + 1 + 1 + 1 + 33 + 1 + 1
|
||||
|
||||
// ToLocalTimeoutWitnessSize 156 bytes
|
||||
// - number_of_witness_elements: 1 byte
|
||||
// - local_delay_sig_length: 1 byte
|
||||
// - local_delay_sig: 73 bytes
|
||||
// - zero_length: 1 byte
|
||||
// - witness_script_length: 1 byte
|
||||
// - witness_script (to_local_script)
|
||||
ToLocalTimeoutWitnessSize = 1 + 1 + 73 + 1 + 1 + ToLocalScriptSize
|
||||
|
||||
// ToLocalPenaltyWitnessSize 157 bytes
|
||||
// - number_of_witness_elements: 1 byte
|
||||
// - revocation_sig_length: 1 byte
|
||||
// - revocation_sig: 73 bytes
|
||||
// - OP_TRUE_length: 1 byte
|
||||
// - OP_TRUE: 1 byte
|
||||
// - witness_script_length: 1 byte
|
||||
// - witness_script (to_local_script)
|
||||
ToLocalPenaltyWitnessSize = 1 + 1 + 73 + 1 + 1 + 1 + ToLocalScriptSize
|
||||
|
||||
// ToRemoteConfirmedScriptSize 37 bytes
|
||||
// - OP_DATA: 1 byte
|
||||
// - to_remote_key: 33 bytes
|
||||
// - OP_CHECKSIGVERIFY: 1 byte
|
||||
// - OP_1: 1 byte
|
||||
// - OP_CHECKSEQUENCEVERIFY: 1 byte
|
||||
ToRemoteConfirmedScriptSize = 1 + 33 + 1 + 1 + 1
|
||||
|
||||
// ToRemoteConfirmedWitnessSize 113 bytes
|
||||
// - number_of_witness_elements: 1 byte
|
||||
// - sig_length: 1 byte
|
||||
// - sig: 73 bytes
|
||||
// - witness_script_length: 1 byte
|
||||
// - witness_script (to_remote_delayed_script)
|
||||
ToRemoteConfirmedWitnessSize = 1 + 1 + 73 + 1 + ToRemoteConfirmedScriptSize
|
||||
|
||||
// AcceptedHtlcScriptSize 143 bytes
|
||||
// - OP_DUP: 1 byte
|
||||
// - OP_HASH160: 1 byte
|
||||
// - OP_DATA: 1 byte (RIPEMD160(SHA256(revocationkey)) length)
|
||||
// - RIPEMD160(SHA256(revocationkey)): 20 bytes
|
||||
// - OP_EQUAL: 1 byte
|
||||
// - OP_IF: 1 byte
|
||||
// - OP_CHECKSIG: 1 byte
|
||||
// - OP_ELSE: 1 byte
|
||||
// - OP_DATA: 1 byte (remotekey length)
|
||||
// - remotekey: 33 bytes
|
||||
// - OP_SWAP: 1 byte
|
||||
// - OP_SIZE: 1 byte
|
||||
// - OP_DATA: 1 byte (32 length)
|
||||
// - 32: 1 byte
|
||||
// - OP_EQUAL: 1 byte
|
||||
// - OP_IF: 1 byte
|
||||
// - OP_HASH160: 1 byte
|
||||
// - OP_DATA: 1 byte (RIPEMD160(payment_hash) length)
|
||||
// - RIPEMD160(payment_hash): 20 bytes
|
||||
// - OP_EQUALVERIFY: 1 byte
|
||||
// - 2: 1 byte
|
||||
// - OP_SWAP: 1 byte
|
||||
// - OP_DATA: 1 byte (localkey length)
|
||||
// - localkey: 33 bytes
|
||||
// - 2: 1 byte
|
||||
// - OP_CHECKMULTISIG: 1 byte
|
||||
// - OP_ELSE: 1 byte
|
||||
// - OP_DROP: 1 byte
|
||||
// - OP_DATA: 1 byte (cltv_expiry length)
|
||||
// - cltv_expiry: 4 bytes
|
||||
// - OP_CHECKLOCKTIMEVERIFY: 1 byte
|
||||
// - OP_DROP: 1 byte
|
||||
// - OP_CHECKSIG: 1 byte
|
||||
// - OP_ENDIF: 1 byte
|
||||
// - OP_1: 1 byte // These 3 extra bytes are used for both confirmed and regular
|
||||
// - OP_CSV: 1 byte // HTLC script types. The size won't be correct in all cases,
|
||||
// - OP_DROP: 1 byte // but it is just an upper bound used for fee estimation in any case.
|
||||
// - OP_ENDIF: 1 byte
|
||||
AcceptedHtlcScriptSize = 3*1 + 20 + 5*1 + 33 + 8*1 + 20 + 4*1 +
|
||||
33 + 5*1 + 4 + 8*1
|
||||
|
||||
// AcceptedHtlcTimeoutWitnessSize 219
|
||||
// - number_of_witness_elements: 1 byte
|
||||
// - sender_sig_length: 1 byte
|
||||
// - sender_sig: 73 bytes
|
||||
// - nil_length: 1 byte
|
||||
// - witness_script_length: 1 byte
|
||||
// - witness_script: (accepted_htlc_script)
|
||||
AcceptedHtlcTimeoutWitnessSize = 1 + 1 + 73 + 1 + 1 + AcceptedHtlcScriptSize
|
||||
|
||||
// AcceptedHtlcPenaltyWitnessSize 252 bytes
|
||||
// - number_of_witness_elements: 1 byte
|
||||
// - revocation_sig_length: 1 byte
|
||||
// - revocation_sig: 73 bytes
|
||||
// - revocation_key_length: 1 byte
|
||||
// - revocation_key: 33 bytes
|
||||
// - witness_script_length: 1 byte
|
||||
// - witness_script (accepted_htlc_script)
|
||||
AcceptedHtlcPenaltyWitnessSize = 1 + 1 + 73 + 1 + 33 + 1 + AcceptedHtlcScriptSize
|
||||
|
||||
// AcceptedHtlcSuccessWitnessSize 322 bytes
|
||||
// - number_of_witness_elements: 1 byte
|
||||
// - nil_length: 1 byte
|
||||
// - sig_alice_length: 1 byte
|
||||
// - sig_alice: 73 bytes
|
||||
// - sig_bob_length: 1 byte
|
||||
// - sig_bob: 73 bytes
|
||||
// - preimage_length: 1 byte
|
||||
// - preimage: 32 bytes
|
||||
// - witness_script_length: 1 byte
|
||||
// - witness_script (accepted_htlc_script)
|
||||
AcceptedHtlcSuccessWitnessSize = 1 + 1 + 1 + 73 + 1 + 73 + 1 + 32 + 1 +
|
||||
AcceptedHtlcScriptSize
|
||||
|
||||
// OfferedHtlcScriptSize 136 bytes
|
||||
// - OP_DUP: 1 byte
|
||||
// - OP_HASH160: 1 byte
|
||||
// - OP_DATA: 1 byte (RIPEMD160(SHA256(revocationkey)) length)
|
||||
// - RIPEMD160(SHA256(revocationkey)): 20 bytes
|
||||
// - OP_EQUAL: 1 byte
|
||||
// - OP_IF: 1 byte
|
||||
// - OP_CHECKSIG: 1 byte
|
||||
// - OP_ELSE: 1 byte
|
||||
// - OP_DATA: 1 byte (remotekey length)
|
||||
// - remotekey: 33 bytes
|
||||
// - OP_SWAP: 1 byte
|
||||
// - OP_SIZE: 1 byte
|
||||
// - OP_DATA: 1 byte (32 length)
|
||||
// - 32: 1 byte
|
||||
// - OP_EQUAL: 1 byte
|
||||
// - OP_NOTIF: 1 byte
|
||||
// - OP_DROP: 1 byte
|
||||
// - 2: 1 byte
|
||||
// - OP_SWAP: 1 byte
|
||||
// - OP_DATA: 1 byte (localkey length)
|
||||
// - localkey: 33 bytes
|
||||
// - 2: 1 byte
|
||||
// - OP_CHECKMULTISIG: 1 byte
|
||||
// - OP_ELSE: 1 byte
|
||||
// - OP_HASH160: 1 byte
|
||||
// - OP_DATA: 1 byte (RIPEMD160(payment_hash) length)
|
||||
// - RIPEMD160(payment_hash): 20 bytes
|
||||
// - OP_EQUALVERIFY: 1 byte
|
||||
// - OP_CHECKSIG: 1 byte
|
||||
// - OP_ENDIF: 1 byte
|
||||
// - OP_1: 1 byte
|
||||
// - OP_CSV: 1 byte
|
||||
// - OP_DROP: 1 byte
|
||||
// - OP_ENDIF: 1 byte
|
||||
OfferedHtlcScriptSize = 3*1 + 20 + 5*1 + 33 + 10*1 + 33 + 5*1 + 20 + 7*1
|
||||
|
||||
// OfferedHtlcSuccessWitnessSize 245 bytes
|
||||
// - number_of_witness_elements: 1 byte
|
||||
// - receiver_sig_length: 1 byte
|
||||
// - receiver_sig: 73 bytes
|
||||
// - payment_preimage_length: 1 byte
|
||||
// - payment_preimage: 32 bytes
|
||||
// - witness_script_length: 1 byte
|
||||
// - witness_script (offered_htlc_script)
|
||||
OfferedHtlcSuccessWitnessSize = 1 + 1 + 73 + 1 + 32 + 1 + OfferedHtlcScriptSize
|
||||
|
||||
// OfferedHtlcTimeoutWitnessSize 285 bytes
|
||||
// - number_of_witness_elements: 1 byte
|
||||
// - nil_length: 1 byte
|
||||
// - sig_alice_length: 1 byte
|
||||
// - sig_alice: 73 bytes
|
||||
// - sig_bob_length: 1 byte
|
||||
// - sig_bob: 73 bytes
|
||||
// - nil_length: 1 byte
|
||||
// - witness_script_length: 1 byte
|
||||
// - witness_script (offered_htlc_script)
|
||||
OfferedHtlcTimeoutWitnessSize = 1 + 1 + 1 + 73 + 1 + 73 + 1 + 1 + OfferedHtlcScriptSize
|
||||
|
||||
// OfferedHtlcPenaltyWitnessSize 246 bytes
|
||||
// - number_of_witness_elements: 1 byte
|
||||
// - revocation_sig_length: 1 byte
|
||||
// - revocation_sig: 73 bytes
|
||||
// - revocation_key_length: 1 byte
|
||||
// - revocation_key: 33 bytes
|
||||
// - witness_script_length: 1 byte
|
||||
// - witness_script (offered_htlc_script)
|
||||
OfferedHtlcPenaltyWitnessSize = 1 + 1 + 73 + 1 + 33 + 1 + OfferedHtlcScriptSize
|
||||
|
||||
// AnchorScriptSize 40 bytes
|
||||
// - pubkey_length: 1 byte
|
||||
// - pubkey: 33 bytes
|
||||
// - OP_CHECKSIG: 1 byte
|
||||
// - OP_IFDUP: 1 byte
|
||||
// - OP_NOTIF: 1 byte
|
||||
// - OP_16: 1 byte
|
||||
// - OP_CSV 1 byte
|
||||
// - OP_ENDIF: 1 byte
|
||||
AnchorScriptSize = 1 + 33 + 6*1
|
||||
|
||||
// AnchorWitnessSize 116 bytes
|
||||
// - number_of_witnes_elements: 1 byte
|
||||
// - signature_length: 1 byte
|
||||
// - signature: 73 bytes
|
||||
// - witness_script_length: 1 byte
|
||||
// - witness_script (anchor_script)
|
||||
AnchorWitnessSize = 1 + 1 + 73 + 1 + AnchorScriptSize
|
||||
)
|
||||
|
||||
// EstimateCommitTxWeight estimate commitment transaction weight depending on
|
||||
// the precalculated weight of base transaction, witness data, which is needed
|
||||
// for paying for funding tx, and htlc weight multiplied by their count.
|
||||
func EstimateCommitTxWeight(count int, prediction bool) int64 {
|
||||
// Make prediction about the size of commitment transaction with
|
||||
// additional HTLC.
|
||||
if prediction {
|
||||
count++
|
||||
}
|
||||
|
||||
htlcWeight := int64(count * HTLCWeight)
|
||||
baseWeight := int64(BaseCommitmentTxWeight)
|
||||
witnessWeight := int64(WitnessCommitmentTxWeight)
|
||||
|
||||
return htlcWeight + baseWeight + witnessWeight
|
||||
}
|
||||
|
||||
// TxWeightEstimator is able to calculate weight estimates for transactions
|
||||
// based on the input and output types. For purposes of estimation, all
|
||||
// signatures are assumed to be of the maximum possible size, 73 bytes. Each
|
||||
// method of the estimator returns an instance with the estimate applied. This
|
||||
// allows callers to chain each of the methods
|
||||
type TxWeightEstimator struct {
|
||||
hasWitness bool
|
||||
inputCount uint32
|
||||
outputCount uint32
|
||||
inputSize int
|
||||
inputWitnessSize int
|
||||
outputSize int
|
||||
}
|
||||
|
||||
// AddP2PKHInput updates the weight estimate to account for an additional input
|
||||
// spending a P2PKH output.
|
||||
func (twe *TxWeightEstimator) AddP2PKHInput() *TxWeightEstimator {
|
||||
twe.inputSize += InputSize + P2PKHScriptSigSize
|
||||
twe.inputWitnessSize++
|
||||
twe.inputCount++
|
||||
|
||||
return twe
|
||||
}
|
||||
|
||||
// AddP2WKHInput updates the weight estimate to account for an additional input
|
||||
// spending a native P2PWKH output.
|
||||
func (twe *TxWeightEstimator) AddP2WKHInput() *TxWeightEstimator {
|
||||
twe.AddWitnessInput(P2WKHWitnessSize)
|
||||
|
||||
return twe
|
||||
}
|
||||
|
||||
// AddWitnessInput updates the weight estimate to account for an additional
|
||||
// input spending a native pay-to-witness output. This accepts the total size
|
||||
// of the witness as a parameter.
|
||||
func (twe *TxWeightEstimator) AddWitnessInput(witnessSize int) *TxWeightEstimator {
|
||||
twe.inputSize += InputSize
|
||||
twe.inputWitnessSize += witnessSize
|
||||
twe.inputCount++
|
||||
twe.hasWitness = true
|
||||
|
||||
return twe
|
||||
}
|
||||
|
||||
// AddNestedP2WKHInput updates the weight estimate to account for an additional
|
||||
// input spending a P2SH output with a nested P2WKH redeem script.
|
||||
func (twe *TxWeightEstimator) AddNestedP2WKHInput() *TxWeightEstimator {
|
||||
twe.inputSize += InputSize + NestedP2WPKHSize
|
||||
twe.inputWitnessSize += P2WKHWitnessSize
|
||||
twe.inputCount++
|
||||
twe.hasWitness = true
|
||||
|
||||
return twe
|
||||
}
|
||||
|
||||
// AddNestedP2WSHInput updates the weight estimate to account for an additional
|
||||
// input spending a P2SH output with a nested P2WSH redeem script.
|
||||
func (twe *TxWeightEstimator) AddNestedP2WSHInput(witnessSize int) *TxWeightEstimator {
|
||||
twe.inputSize += InputSize + NestedP2WSHSize
|
||||
twe.inputWitnessSize += witnessSize
|
||||
twe.inputCount++
|
||||
twe.hasWitness = true
|
||||
|
||||
return twe
|
||||
}
|
||||
|
||||
// AddP2PKHOutput updates the weight estimate to account for an additional P2PKH
|
||||
// output.
|
||||
func (twe *TxWeightEstimator) AddP2PKHOutput() *TxWeightEstimator {
|
||||
twe.outputSize += P2PKHOutputSize
|
||||
twe.outputCount++
|
||||
|
||||
return twe
|
||||
}
|
||||
|
||||
// AddP2WKHOutput updates the weight estimate to account for an additional
|
||||
// native P2WKH output.
|
||||
func (twe *TxWeightEstimator) AddP2WKHOutput() *TxWeightEstimator {
|
||||
twe.outputSize += P2WKHOutputSize
|
||||
twe.outputCount++
|
||||
|
||||
return twe
|
||||
}
|
||||
|
||||
// AddP2WSHOutput updates the weight estimate to account for an additional
|
||||
// native P2WSH output.
|
||||
func (twe *TxWeightEstimator) AddP2WSHOutput() *TxWeightEstimator {
|
||||
twe.outputSize += P2WSHOutputSize
|
||||
twe.outputCount++
|
||||
|
||||
return twe
|
||||
}
|
||||
|
||||
// AddP2SHOutput updates the weight estimate to account for an additional P2SH
|
||||
// output.
|
||||
func (twe *TxWeightEstimator) AddP2SHOutput() *TxWeightEstimator {
|
||||
twe.outputSize += P2SHOutputSize
|
||||
twe.outputCount++
|
||||
|
||||
return twe
|
||||
}
|
||||
|
||||
// Weight gets the estimated weight of the transaction.
|
||||
func (twe *TxWeightEstimator) Weight() int {
|
||||
txSizeStripped := BaseTxSize +
|
||||
wire.VarIntSerializeSize(uint64(twe.inputCount)) + twe.inputSize +
|
||||
wire.VarIntSerializeSize(uint64(twe.outputCount)) + twe.outputSize
|
||||
weight := txSizeStripped * witnessScaleFactor
|
||||
if twe.hasWitness {
|
||||
weight += WitnessHeaderSize + twe.inputWitnessSize
|
||||
}
|
||||
return weight
|
||||
}
|
||||
|
||||
// VSize gets the estimated virtual size of the transactions, in vbytes.
|
||||
func (twe *TxWeightEstimator) VSize() int {
|
||||
// A tx's vsize is 1/4 of the weight, rounded up.
|
||||
return (twe.Weight() + witnessScaleFactor - 1) / witnessScaleFactor
|
||||
}
|
||||
191
vendor/github.com/lightningnetwork/lnd/input/test_utils.go
generated
vendored
Normal file
191
vendor/github.com/lightningnetwork/lnd/input/test_utils.go
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
// For simplicity a single priv key controls all of our test outputs.
|
||||
testWalletPrivKey = []byte{
|
||||
0x2b, 0xd8, 0x06, 0xc9, 0x7f, 0x0e, 0x00, 0xaf,
|
||||
0x1a, 0x1f, 0xc3, 0x32, 0x8f, 0xa7, 0x63, 0xa9,
|
||||
0x26, 0x97, 0x23, 0xc8, 0xdb, 0x8f, 0xac, 0x4f,
|
||||
0x93, 0xaf, 0x71, 0xdb, 0x18, 0x6d, 0x6e, 0x90,
|
||||
}
|
||||
|
||||
// We're alice :)
|
||||
bobsPrivKey = []byte{
|
||||
0x81, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
|
||||
0x63, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
|
||||
0xd, 0xe7, 0x95, 0xe4, 0xb7, 0x25, 0xb8, 0x4d,
|
||||
0x1e, 0xb, 0x4c, 0xfd, 0x9e, 0xc5, 0x8c, 0xe9,
|
||||
}
|
||||
|
||||
// Use a hard-coded HD seed.
|
||||
testHdSeed = chainhash.Hash{
|
||||
0xb7, 0x94, 0x38, 0x5f, 0x2d, 0x1e, 0xf7, 0xab,
|
||||
0x4d, 0x92, 0x73, 0xd1, 0x90, 0x63, 0x81, 0xb4,
|
||||
0x4f, 0x2f, 0x6f, 0x25, 0x88, 0xa3, 0xef, 0xb9,
|
||||
0x6a, 0x49, 0x18, 0x83, 0x31, 0x98, 0x47, 0x53,
|
||||
}
|
||||
)
|
||||
|
||||
// MockSigner is a simple implementation of the Signer interface. Each one has
|
||||
// a set of private keys in a slice and can sign messages using the appropriate
|
||||
// one.
|
||||
type MockSigner struct {
|
||||
Privkeys []*btcec.PrivateKey
|
||||
NetParams *chaincfg.Params
|
||||
}
|
||||
|
||||
// SignOutputRaw generates a signature for the passed transaction according to
|
||||
// the data within the passed SignDescriptor.
|
||||
func (m *MockSigner) SignOutputRaw(tx *wire.MsgTx,
|
||||
signDesc *SignDescriptor) (Signature, error) {
|
||||
|
||||
pubkey := signDesc.KeyDesc.PubKey
|
||||
switch {
|
||||
case signDesc.SingleTweak != nil:
|
||||
pubkey = TweakPubKeyWithTweak(pubkey, signDesc.SingleTweak)
|
||||
case signDesc.DoubleTweak != nil:
|
||||
pubkey = DeriveRevocationPubkey(pubkey, signDesc.DoubleTweak.PubKey())
|
||||
}
|
||||
|
||||
hash160 := btcutil.Hash160(pubkey.SerializeCompressed())
|
||||
privKey := m.findKey(hash160, signDesc.SingleTweak, signDesc.DoubleTweak)
|
||||
if privKey == nil {
|
||||
return nil, fmt.Errorf("Mock signer does not have key")
|
||||
}
|
||||
|
||||
sig, err := txscript.RawTxInWitnessSignature(tx, signDesc.SigHashes,
|
||||
signDesc.InputIndex, signDesc.Output.Value, signDesc.WitnessScript,
|
||||
signDesc.HashType, privKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return btcec.ParseDERSignature(sig[:len(sig)-1], btcec.S256())
|
||||
}
|
||||
|
||||
// ComputeInputScript generates a complete InputIndex for the passed transaction
|
||||
// with the signature as defined within the passed SignDescriptor. This method
|
||||
// should be capable of generating the proper input script for both regular
|
||||
// p2wkh output and p2wkh outputs nested within a regular p2sh output.
|
||||
func (m *MockSigner) ComputeInputScript(tx *wire.MsgTx, signDesc *SignDescriptor) (*Script, error) {
|
||||
scriptType, addresses, _, err := txscript.ExtractPkScriptAddrs(
|
||||
signDesc.Output.PkScript, m.NetParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch scriptType {
|
||||
case txscript.PubKeyHashTy:
|
||||
privKey := m.findKey(addresses[0].ScriptAddress(), signDesc.SingleTweak,
|
||||
signDesc.DoubleTweak)
|
||||
if privKey == nil {
|
||||
return nil, fmt.Errorf("Mock signer does not have key for "+
|
||||
"address %v", addresses[0])
|
||||
}
|
||||
|
||||
sigScript, err := txscript.SignatureScript(
|
||||
tx, signDesc.InputIndex, signDesc.Output.PkScript,
|
||||
txscript.SigHashAll, privKey, true,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Script{SigScript: sigScript}, nil
|
||||
|
||||
case txscript.WitnessV0PubKeyHashTy:
|
||||
privKey := m.findKey(addresses[0].ScriptAddress(), signDesc.SingleTweak,
|
||||
signDesc.DoubleTweak)
|
||||
if privKey == nil {
|
||||
return nil, fmt.Errorf("Mock signer does not have key for "+
|
||||
"address %v", addresses[0])
|
||||
}
|
||||
|
||||
witnessScript, err := txscript.WitnessSignature(tx, signDesc.SigHashes,
|
||||
signDesc.InputIndex, signDesc.Output.Value,
|
||||
signDesc.Output.PkScript, txscript.SigHashAll, privKey, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Script{Witness: witnessScript}, nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("Unexpected script type: %v", scriptType)
|
||||
}
|
||||
}
|
||||
|
||||
// findKey searches through all stored private keys and returns one
|
||||
// corresponding to the hashed pubkey if it can be found. The public key may
|
||||
// either correspond directly to the private key or to the private key with a
|
||||
// tweak applied.
|
||||
func (m *MockSigner) findKey(needleHash160 []byte, singleTweak []byte,
|
||||
doubleTweak *btcec.PrivateKey) *btcec.PrivateKey {
|
||||
|
||||
for _, privkey := range m.Privkeys {
|
||||
// First check whether public key is directly derived from private key.
|
||||
hash160 := btcutil.Hash160(privkey.PubKey().SerializeCompressed())
|
||||
if bytes.Equal(hash160, needleHash160) {
|
||||
return privkey
|
||||
}
|
||||
|
||||
// Otherwise check if public key is derived from tweaked private key.
|
||||
switch {
|
||||
case singleTweak != nil:
|
||||
privkey = TweakPrivKey(privkey, singleTweak)
|
||||
case doubleTweak != nil:
|
||||
privkey = DeriveRevocationPrivKey(privkey, doubleTweak)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
hash160 = btcutil.Hash160(privkey.PubKey().SerializeCompressed())
|
||||
if bytes.Equal(hash160, needleHash160) {
|
||||
return privkey
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// pubkeyFromHex parses a Bitcoin public key from a hex encoded string.
|
||||
func pubkeyFromHex(keyHex string) (*btcec.PublicKey, error) {
|
||||
bytes, err := hex.DecodeString(keyHex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return btcec.ParsePubKey(bytes, btcec.S256())
|
||||
}
|
||||
|
||||
// privkeyFromHex parses a Bitcoin private key from a hex encoded string.
|
||||
func privkeyFromHex(keyHex string) (*btcec.PrivateKey, error) {
|
||||
bytes, err := hex.DecodeString(keyHex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key, _ := btcec.PrivKeyFromBytes(btcec.S256(), bytes)
|
||||
return key, nil
|
||||
|
||||
}
|
||||
|
||||
// pubkeyToHex serializes a Bitcoin public key to a hex encoded string.
|
||||
func pubkeyToHex(key *btcec.PublicKey) string {
|
||||
return hex.EncodeToString(key.SerializeCompressed())
|
||||
}
|
||||
|
||||
// privkeyFromHex serializes a Bitcoin private key to a hex encoded string.
|
||||
func privkeyToHex(key *btcec.PrivateKey) string {
|
||||
return hex.EncodeToString(key.Serialize())
|
||||
}
|
||||
46
vendor/github.com/lightningnetwork/lnd/input/txout.go
generated
vendored
Normal file
46
vendor/github.com/lightningnetwork/lnd/input/txout.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
)
|
||||
|
||||
// writeTxOut serializes a wire.TxOut struct into the passed io.Writer stream.
|
||||
func writeTxOut(w io.Writer, txo *wire.TxOut) error {
|
||||
var scratch [8]byte
|
||||
|
||||
binary.BigEndian.PutUint64(scratch[:], uint64(txo.Value))
|
||||
if _, err := w.Write(scratch[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := wire.WriteVarBytes(w, 0, txo.PkScript); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// readTxOut deserializes a wire.TxOut struct from the passed io.Reader stream.
|
||||
func readTxOut(r io.Reader, txo *wire.TxOut) error {
|
||||
var scratch [8]byte
|
||||
|
||||
if _, err := io.ReadFull(r, scratch[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
value := int64(binary.BigEndian.Uint64(scratch[:]))
|
||||
|
||||
pkScript, err := wire.ReadVarBytes(r, 0, 80, "pkScript")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*txo = wire.TxOut{
|
||||
Value: value,
|
||||
PkScript: pkScript,
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
443
vendor/github.com/lightningnetwork/lnd/input/witnessgen.go
generated
vendored
Normal file
443
vendor/github.com/lightningnetwork/lnd/input/witnessgen.go
generated
vendored
Normal file
@@ -0,0 +1,443 @@
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
// 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
|
||||
|
||||
// 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
|
||||
)
|
||||
|
||||
// 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 HtlcAcceptedSuccessSecondLevel:
|
||||
return "HtlcAcceptedSuccessSecondLevel"
|
||||
|
||||
case HtlcOfferedRemoteTimeout:
|
||||
return "HtlcOfferedRemoteTimeout"
|
||||
|
||||
case HtlcAcceptedRemoteSuccess:
|
||||
return "HtlcAcceptedRemoteSuccess"
|
||||
|
||||
case HtlcSecondLevelRevoke:
|
||||
return "HtlcSecondLevelRevoke"
|
||||
|
||||
case WitnessKeyHash:
|
||||
return "WitnessKeyHash"
|
||||
|
||||
case NestedWitnessKeyHash:
|
||||
return "NestedWitnessKeyHash"
|
||||
|
||||
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) {
|
||||
|
||||
desc := descriptor
|
||||
desc.SigHashes = hc
|
||||
desc.InputIndex = inputIndex
|
||||
|
||||
switch wt {
|
||||
case CommitmentTimeLock:
|
||||
witness, err := CommitSpendTimeout(signer, desc, tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Script{
|
||||
Witness: witness,
|
||||
}, nil
|
||||
|
||||
case CommitmentToRemoteConfirmed:
|
||||
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:
|
||||
witness, err := HtlcSecondLevelSpend(signer, desc, tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Script{
|
||||
Witness: witness,
|
||||
}, nil
|
||||
|
||||
case HtlcAcceptedSuccessSecondLevel:
|
||||
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 NestedWitnessKeyHash:
|
||||
return signer.ComputeInputScript(tx, desc)
|
||||
|
||||
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
|
||||
|
||||
// 1 CSV time locked output to us on remote commitment.
|
||||
case CommitmentToRemoteConfirmed:
|
||||
return ToRemoteConfirmedWitnessSize, 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
|
||||
|
||||
// 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
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user