/ input / script_desc.go
script_desc.go
  1  package input
  2  
  3  import (
  4  	"errors"
  5  
  6  	"github.com/btcsuite/btcd/btcec/v2"
  7  	"github.com/btcsuite/btcd/txscript"
  8  	"github.com/lightningnetwork/lnd/lnutils"
  9  )
 10  
 11  // ErrUnknownScriptType is returned when an unknown script type is encountered.
 12  var ErrUnknownScriptType = errors.New("unknown script type")
 13  
 14  // ScriptPath is used to indicate the spending path of a given script. Possible
 15  // paths include: timeout, success, revocation, and others.
 16  type ScriptPath uint8
 17  
 18  const (
 19  	// ScriptPathTimeout is a script path that can be taken only after a
 20  	// timeout has elapsed.
 21  	ScriptPathTimeout ScriptPath = iota
 22  
 23  	// ScriptPathSuccess is a script path that can be taken only with some
 24  	// secret data.
 25  	ScriptPathSuccess
 26  
 27  	// ScriptPathRevocation is a script path used when a contract has been
 28  	// breached.
 29  	ScriptPathRevocation
 30  
 31  	// ScriptPathDelay is a script path used when a contract has relative
 32  	// delay that must elapse before it can be swept.
 33  	ScriptPathDelay
 34  )
 35  
 36  // ScriptDescriptor is an interface that abstracts over the various ways a
 37  // pkScript can be spent from an output. This supports both normal p2wsh
 38  // (witness script, etc.), and also tapscript paths which have distinct
 39  // tapscript leaves.
 40  type ScriptDescriptor interface {
 41  	// PkScript is the public key script that commits to the final
 42  	// contract.
 43  	PkScript() []byte
 44  
 45  	// WitnessScriptToSign returns the witness script that we'll use when
 46  	// signing for the remote party, and also verifying signatures on our
 47  	// transactions. As an example, when we create an outgoing HTLC for the
 48  	// remote party, we want to sign their success path.
 49  	//
 50  	// TODO(roasbeef): break out into HTLC specific desc? or Branching Desc
 51  	// w/ the below?
 52  	WitnessScriptToSign() []byte
 53  
 54  	// WitnessScriptForPath returns the witness script for the given
 55  	// spending path. An error is returned if the path is unknown. This is
 56  	// useful as when constructing a control block for a given path, one
 57  	// also needs witness script being signed.
 58  	WitnessScriptForPath(path ScriptPath) ([]byte, error)
 59  }
 60  
 61  // TapscriptDescriptor is a super-set of the normal script multiplexer that
 62  // adds in taproot specific details such as the control block, or top-level tap
 63  // tweak.
 64  type TapscriptDescriptor interface {
 65  	ScriptDescriptor
 66  
 67  	// CtrlBlockForPath returns the control block for the given spending
 68  	// path. For unknown paths, an error is returned.
 69  	CtrlBlockForPath(path ScriptPath) (*txscript.ControlBlock, error)
 70  
 71  	// TapTweak returns the top-level taproot tweak for the script.
 72  	TapTweak() []byte
 73  
 74  	// TapScriptTree returns the underlying tapscript tree.
 75  	TapScriptTree() *txscript.IndexedTapScriptTree
 76  
 77  	// Tree returns the underlying ScriptTree.
 78  	Tree() ScriptTree
 79  }
 80  
 81  // ScriptTree holds the contents needed to spend a script within a tapscript
 82  // tree.
 83  type ScriptTree struct {
 84  	// InternalKey is the internal key of the Taproot output key.
 85  	InternalKey *btcec.PublicKey
 86  
 87  	// TaprootKey is the key that will be used to generate the taproot
 88  	// output.
 89  	TaprootKey *btcec.PublicKey
 90  
 91  	// TapscriptTree is the full tapscript tree that also includes the
 92  	// control block needed to spend each of the leaves.
 93  	TapscriptTree *txscript.IndexedTapScriptTree
 94  
 95  	// TapscriptTreeRoot is the root hash of the tapscript tree.
 96  	TapscriptRoot []byte
 97  }
 98  
 99  // PkScript is the public key script that commits to the final contract.
100  func (s *ScriptTree) PkScript() []byte {
101  	// Script building can never internally return an error, so we ignore
102  	// the error to simplify the interface.
103  	pkScript, _ := PayToTaprootScript(s.TaprootKey)
104  	return pkScript
105  }
106  
107  // TapTweak returns the top-level taproot tweak for the script.
108  func (s *ScriptTree) TapTweak() []byte {
109  	return lnutils.ByteSlice(s.TapscriptTree.RootNode.TapHash())
110  }
111  
112  // TapScriptTree returns the underlying tapscript tree.
113  func (s *ScriptTree) TapScriptTree() *txscript.IndexedTapScriptTree {
114  	return s.TapscriptTree
115  }