Skip to content

Commit 3865a77

Browse files
authored
Merge pull request #114 from sputn1ck/chantools_external_amt
`recoverloopin`: allow setting output value
2 parents 399a23a + ad3c1ad commit 3865a77

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

cmd/chantools/recoverloopin.go

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/hex"
66
"fmt"
77

8+
"github.com/btcsuite/btcd/btcutil"
89
"github.com/btcsuite/btcd/chaincfg/chainhash"
910
"github.com/btcsuite/btcd/txscript"
1011
"github.com/btcsuite/btcd/wire"
@@ -23,6 +24,7 @@ type recoverLoopInCommand struct {
2324
Vout uint32
2425
SwapHash string
2526
SweepAddr string
27+
OutputAmt uint64
2628
FeeRate uint32
2729
StartKeyIndex int
2830
NumTries int
@@ -92,6 +94,9 @@ func newRecoverLoopInCommand() *cobra.Command {
9294
&cc.Publish, "publish", false, "publish sweep TX to the chain "+
9395
"API instead of just printing the TX",
9496
)
97+
cc.cmd.Flags().Uint64Var(
98+
&cc.OutputAmt, "output_amt", 0, "amount of the output to sweep",
99+
)
95100

96101
cc.rootKey = newRootKey(cc.cmd, "deriving starting key")
97102

@@ -153,8 +158,20 @@ func (c *recoverLoopInCommand) Execute(_ *cobra.Command, _ []string) error {
153158
return fmt.Errorf("swap not found")
154159
}
155160

161+
// If the swap is an external htlc, we require the output amount to be
162+
// set, as a lot of failure cases steam from the output amount being
163+
// wrong.
164+
if loopIn.Contract.ExternalHtlc && c.OutputAmt == 0 {
165+
return fmt.Errorf("output_amt is required for external htlc")
166+
}
167+
156168
fmt.Println("Loop expires at block height", loopIn.Contract.CltvExpiry)
157169

170+
outputValue := loopIn.Contract.AmountRequested
171+
if c.OutputAmt != 0 {
172+
outputValue = btcutil.Amount(c.OutputAmt)
173+
}
174+
158175
// Get the swaps htlc.
159176
htlc, err := loop.GetHtlc(
160177
loopIn.Hash, &loopIn.Contract.SwapContract, chainParams,
@@ -208,7 +225,7 @@ func (c *recoverLoopInCommand) Execute(_ *cobra.Command, _ []string) error {
208225
// Add output for the destination address.
209226
sweepTx.AddTxOut(&wire.TxOut{
210227
PkScript: sweepScript,
211-
Value: int64(loopIn.Contract.AmountRequested) - int64(fee),
228+
Value: int64(outputValue) - int64(fee),
212229
})
213230

214231
// If the htlc is version 2, we need to brute force the key locator, as
@@ -218,8 +235,9 @@ func (c *recoverLoopInCommand) Execute(_ *cobra.Command, _ []string) error {
218235
fmt.Println("Brute forcing key index...")
219236
for i := c.StartKeyIndex; i < c.StartKeyIndex+c.NumTries; i++ {
220237
rawTx, err = getSignedTx(
221-
signer, loopIn, sweepTx, htlc,
238+
signer, sweepTx, htlc,
222239
keychain.KeyFamily(swap.KeyFamily), uint32(i),
240+
outputValue,
223241
)
224242
if err == nil {
225243
break
@@ -232,9 +250,10 @@ func (c *recoverLoopInCommand) Execute(_ *cobra.Command, _ []string) error {
232250
}
233251
} else {
234252
rawTx, err = getSignedTx(
235-
signer, loopIn, sweepTx, htlc,
253+
signer, sweepTx, htlc,
236254
loopIn.Contract.HtlcKeys.ClientScriptKeyLocator.Family,
237255
loopIn.Contract.HtlcKeys.ClientScriptKeyLocator.Index,
256+
outputValue,
238257
)
239258
if err != nil {
240259
return err
@@ -260,14 +279,14 @@ func (c *recoverLoopInCommand) Execute(_ *cobra.Command, _ []string) error {
260279
return nil
261280
}
262281

263-
func getSignedTx(signer *lnd.Signer, loopIn *loopdb.LoopIn, sweepTx *wire.MsgTx,
264-
htlc *swap.Htlc, keyFamily keychain.KeyFamily,
265-
keyIndex uint32) ([]byte, error) {
282+
func getSignedTx(signer *lnd.Signer, sweepTx *wire.MsgTx, htlc *swap.Htlc,
283+
keyFamily keychain.KeyFamily, keyIndex uint32,
284+
outputValue btcutil.Amount) ([]byte, error) {
266285

267286
// Create the sign descriptor.
268287
prevTxOut := &wire.TxOut{
269288
PkScript: htlc.PkScript,
270-
Value: int64(loopIn.Contract.AmountRequested),
289+
Value: int64(outputValue),
271290
}
272291
prevOutputFetcher := txscript.NewCannedPrevOutputFetcher(
273292
prevTxOut.PkScript, prevTxOut.Value,

0 commit comments

Comments
 (0)