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 }