2
0
mirror of https://github.com/guggero/chantools synced 2024-11-07 03:20:43 +00:00

Merge pull request #114 from sputn1ck/chantools_external_amt

`recoverloopin`: allow setting output value
This commit is contained in:
Oliver Gugger 2024-01-12 11:28:36 +01:00 committed by GitHub
commit 3865a7757e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,6 +5,7 @@ import (
"encoding/hex"
"fmt"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
@ -23,6 +24,7 @@ type recoverLoopInCommand struct {
Vout uint32
SwapHash string
SweepAddr string
OutputAmt uint64
FeeRate uint32
StartKeyIndex int
NumTries int
@ -92,6 +94,9 @@ func newRecoverLoopInCommand() *cobra.Command {
&cc.Publish, "publish", false, "publish sweep TX to the chain "+
"API instead of just printing the TX",
)
cc.cmd.Flags().Uint64Var(
&cc.OutputAmt, "output_amt", 0, "amount of the output to sweep",
)
cc.rootKey = newRootKey(cc.cmd, "deriving starting key")
@ -153,8 +158,20 @@ func (c *recoverLoopInCommand) Execute(_ *cobra.Command, _ []string) error {
return fmt.Errorf("swap not found")
}
// If the swap is an external htlc, we require the output amount to be
// set, as a lot of failure cases steam from the output amount being
// wrong.
if loopIn.Contract.ExternalHtlc && c.OutputAmt == 0 {
return fmt.Errorf("output_amt is required for external htlc")
}
fmt.Println("Loop expires at block height", loopIn.Contract.CltvExpiry)
outputValue := loopIn.Contract.AmountRequested
if c.OutputAmt != 0 {
outputValue = btcutil.Amount(c.OutputAmt)
}
// Get the swaps htlc.
htlc, err := loop.GetHtlc(
loopIn.Hash, &loopIn.Contract.SwapContract, chainParams,
@ -208,7 +225,7 @@ func (c *recoverLoopInCommand) Execute(_ *cobra.Command, _ []string) error {
// Add output for the destination address.
sweepTx.AddTxOut(&wire.TxOut{
PkScript: sweepScript,
Value: int64(loopIn.Contract.AmountRequested) - int64(fee),
Value: int64(outputValue) - int64(fee),
})
// 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 {
fmt.Println("Brute forcing key index...")
for i := c.StartKeyIndex; i < c.StartKeyIndex+c.NumTries; i++ {
rawTx, err = getSignedTx(
signer, loopIn, sweepTx, htlc,
signer, sweepTx, htlc,
keychain.KeyFamily(swap.KeyFamily), uint32(i),
outputValue,
)
if err == nil {
break
@ -232,9 +250,10 @@ func (c *recoverLoopInCommand) Execute(_ *cobra.Command, _ []string) error {
}
} else {
rawTx, err = getSignedTx(
signer, loopIn, sweepTx, htlc,
signer, sweepTx, htlc,
loopIn.Contract.HtlcKeys.ClientScriptKeyLocator.Family,
loopIn.Contract.HtlcKeys.ClientScriptKeyLocator.Index,
outputValue,
)
if err != nil {
return err
@ -260,14 +279,14 @@ func (c *recoverLoopInCommand) Execute(_ *cobra.Command, _ []string) error {
return nil
}
func getSignedTx(signer *lnd.Signer, loopIn *loopdb.LoopIn, sweepTx *wire.MsgTx,
htlc *swap.Htlc, keyFamily keychain.KeyFamily,
keyIndex uint32) ([]byte, error) {
func getSignedTx(signer *lnd.Signer, sweepTx *wire.MsgTx, htlc *swap.Htlc,
keyFamily keychain.KeyFamily, keyIndex uint32,
outputValue btcutil.Amount) ([]byte, error) {
// Create the sign descriptor.
prevTxOut := &wire.TxOut{
PkScript: htlc.PkScript,
Value: int64(loopIn.Contract.AmountRequested),
Value: int64(outputValue),
}
prevOutputFetcher := txscript.NewCannedPrevOutputFetcher(
prevTxOut.PkScript, prevTxOut.Value,