@@ -14,6 +14,7 @@ import (
1414	"github.com/guggero/chantools/dataformat" 
1515	"github.com/guggero/chantools/lnd" 
1616	"github.com/lightningnetwork/lnd/input" 
17+ 	"github.com/lightningnetwork/lnd/keychain" 
1718	"github.com/lightningnetwork/lnd/lnwallet/chainfee" 
1819	"github.com/spf13/cobra" 
1920)
@@ -104,28 +105,28 @@ func (c *sweepTimeLockCommand) Execute(_ *cobra.Command, _ []string) error {
104105	if  c .FeeRate  ==  0  {
105106		c .FeeRate  =  defaultFeeSatPerVByte 
106107	}
107- 	return  sweepTimeLock (
108+ 	return  sweepTimeLockFromSummary (
108109		extendedKey , c .APIURL , entries , c .SweepAddr , c .MaxCsvLimit ,
109110		c .Publish , c .FeeRate ,
110111	)
111112}
112113
113- func  sweepTimeLock (extendedKey  * hdkeychain.ExtendedKey , apiURL  string ,
114+ type  sweepTarget  struct  {
115+ 	channelPoint         string 
116+ 	txid                 chainhash.Hash 
117+ 	index                uint32 
118+ 	lockScript           []byte 
119+ 	value                int64 
120+ 	commitPoint          * btcec.PublicKey 
121+ 	revocationBasePoint  * btcec.PublicKey 
122+ 	delayBasePointDesc   * keychain.KeyDescriptor 
123+ }
124+ 
125+ func  sweepTimeLockFromSummary (extendedKey  * hdkeychain.ExtendedKey , apiURL  string ,
114126	entries  []* dataformat.SummaryEntry , sweepAddr  string ,
115127	maxCsvTimeout  uint16 , publish  bool , feeRate  uint16 ) error  {
116128
117- 	// Create signer and transaction template. 
118- 	signer  :=  & lnd.Signer {
119- 		ExtendedKey : extendedKey ,
120- 		ChainParams : chainParams ,
121- 	}
122- 	api  :=  & btc.ExplorerAPI {BaseURL : apiURL }
123- 
124- 	sweepTx  :=  wire .NewMsgTx (2 )
125- 	totalOutputValue  :=  int64 (0 )
126- 	signDescs  :=  make ([]* input.SignDescriptor , 0 )
127- 	var  estimator  input.TxWeightEstimator 
128- 
129+ 	targets  :=  make ([]* sweepTarget , 0 , len (entries ))
129130	for  _ , entry  :=  range  entries  {
130131		// Skip entries that can't be swept. 
131132		if  entry .ForceClose  ==  nil  || 
@@ -169,44 +170,84 @@ func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiURL string,
169170		}
170171		revBase , err  :=  pubKeyFromHex (fc .RevocationBasePoint .PubKey )
171172		if  err  !=  nil  {
172- 			return  fmt .Errorf ("error parsing commit point: %v" , err )
173+ 			return  fmt .Errorf ("error parsing revocation base " + 
174+ 				"point: %v" , err )
173175		}
174- 		delayDesc  :=  fc .DelayBasePoint .Desc ()
175- 		delayPrivKey , err  :=  signer .FetchPrivKey (delayDesc )
176+ 		delayDesc , err  :=  fc .DelayBasePoint .Desc ()
176177		if  err  !=  nil  {
177- 			return  fmt .Errorf ("error getting private key: %v" , err )
178+ 			return  fmt .Errorf ("error parsing delay base point: %v" ,
179+ 				err )
178180		}
179- 		delayBase  :=  delayPrivKey .PubKey ()
180181
181182		lockScript , err  :=  hex .DecodeString (fc .Outs [txindex ].Script )
182183		if  err  !=  nil  {
183184			return  fmt .Errorf ("error parsing target script: %v" ,
184185				err )
185186		}
186187
188+ 		// Create the transaction input. 
189+ 		txHash , err  :=  chainhash .NewHashFromStr (fc .TXID )
190+ 		if  err  !=  nil  {
191+ 			return  fmt .Errorf ("error parsing tx hash: %v" , err )
192+ 		}
193+ 
194+ 		targets  =  append (targets , & sweepTarget {
195+ 			channelPoint :        entry .ChannelPoint ,
196+ 			txid :                * txHash ,
197+ 			index :               uint32 (txindex ),
198+ 			lockScript :          lockScript ,
199+ 			value :               int64 (fc .Outs [txindex ].Value ),
200+ 			commitPoint :         commitPoint ,
201+ 			revocationBasePoint : revBase ,
202+ 			delayBasePointDesc :  delayDesc ,
203+ 		})
204+ 	}
205+ 
206+ 	return  sweepTimeLock (
207+ 		extendedKey , apiURL , targets , sweepAddr , maxCsvTimeout , publish ,
208+ 		feeRate ,
209+ 	)
210+ }
211+ 
212+ func  sweepTimeLock (extendedKey  * hdkeychain.ExtendedKey , apiURL  string ,
213+ 	targets  []* sweepTarget , sweepAddr  string , maxCsvTimeout  uint16 ,
214+ 	publish  bool , feeRate  uint16 ) error  {
215+ 
216+ 	// Create signer and transaction template. 
217+ 	signer  :=  & lnd.Signer {
218+ 		ExtendedKey : extendedKey ,
219+ 		ChainParams : chainParams ,
220+ 	}
221+ 	api  :=  & btc.ExplorerAPI {BaseURL : apiURL }
222+ 
223+ 	sweepTx  :=  wire .NewMsgTx (2 )
224+ 	totalOutputValue  :=  int64 (0 )
225+ 	signDescs  :=  make ([]* input.SignDescriptor , 0 )
226+ 	var  estimator  input.TxWeightEstimator 
227+ 
228+ 	for  _ , target  :=  range  targets  {
187229		// We can't rely on the CSV delay of the channel DB to be 
188230		// correct. But it doesn't cost us a lot to just brute force it. 
189231		csvTimeout , script , scriptHash , err  :=  bruteForceDelay (
190- 			input .TweakPubKey (delayBase , commitPoint ),
191- 			input .DeriveRevocationPubkey (revBase , commitPoint ),
192- 			lockScript , maxCsvTimeout ,
232+ 			input .TweakPubKey (
233+ 				target .delayBasePointDesc .PubKey ,
234+ 				target .commitPoint ,
235+ 			), input .DeriveRevocationPubkey (
236+ 				target .revocationBasePoint ,
237+ 				target .commitPoint ,
238+ 			), target .lockScript , maxCsvTimeout ,
193239		)
194240		if  err  !=  nil  {
195241			log .Errorf ("Could not create matching script for %s " + 
196- 				"or csv too high: %v" , entry .ChannelPoint ,
197- 				err )
242+ 				"or csv too high: %v" , target .channelPoint , err )
198243			continue 
199244		}
200245
201246		// Create the transaction input. 
202- 		txHash , err  :=  chainhash .NewHashFromStr (fc .TXID )
203- 		if  err  !=  nil  {
204- 			return  fmt .Errorf ("error parsing tx hash: %v" , err )
205- 		}
206247		sweepTx .TxIn  =  append (sweepTx .TxIn , & wire.TxIn {
207248			PreviousOutPoint : wire.OutPoint {
208- 				Hash :  * txHash ,
209- 				Index : uint32 ( txindex ) ,
249+ 				Hash :  target . txid ,
250+ 				Index : target . index ,
210251			},
211252			Sequence : input .LockTimeToSequence (
212253				false , uint32 (csvTimeout ),
@@ -215,18 +256,19 @@ func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiURL string,
215256
216257		// Create the sign descriptor for the input. 
217258		signDesc  :=  & input.SignDescriptor {
218- 			KeyDesc : * delayDesc ,
259+ 			KeyDesc : * target . delayBasePointDesc ,
219260			SingleTweak : input .SingleTweakBytes (
220- 				commitPoint , delayBase ,
261+ 				target .commitPoint ,
262+ 				target .delayBasePointDesc .PubKey ,
221263			),
222264			WitnessScript : script ,
223265			Output : & wire.TxOut {
224266				PkScript : scriptHash ,
225- 				Value :    int64 ( fc . Outs [ txindex ]. Value ) ,
267+ 				Value :    target . value ,
226268			},
227269			HashType : txscript .SigHashAll ,
228270		}
229- 		totalOutputValue  +=  int64 ( fc . Outs [ txindex ]. Value ) 
271+ 		totalOutputValue  +=  target . value 
230272		signDescs  =  append (signDescs , signDesc )
231273
232274		// Account for the input weight. 
0 commit comments