lncli: allow final transaction as raw hex in PSBT funding flow

This commit is contained in:
Oliver Gugger 2020-09-07 18:02:42 +02:00
parent c4ada8a592
commit 154dc1af66
No known key found for this signature in database
GPG Key ID: 8E4256593F177720

View File

@ -1,6 +1,7 @@
package main
import (
"bytes"
"context"
"crypto/rand"
"encoding/base64"
@ -11,6 +12,7 @@ import (
"strings"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnwallet/chanfunding"
@ -43,9 +45,9 @@ Base64 encoded PSBT: `
userMsgSign = `
PSBT verified by lnd, please continue the funding flow by signing the PSBT by
all required parties/devices. Once the transaction is fully signed, paste it
again here.
again here either in base64 PSBT or hex encoded raw wire TX format.
Base64 encoded signed PSBT: `
Signed base64 encoded PSBT or hex encoded raw wire TX: `
)
// TODO(roasbeef): change default number of confirmations
@ -505,7 +507,7 @@ func openChannelPsbt(ctx *cli.Context, client lnrpc.LightningClient,
return fmt.Errorf("reading from console "+
"failed: %v", err)
}
psbt, err := base64.StdEncoding.DecodeString(
fundedPsbt, err := base64.StdEncoding.DecodeString(
strings.TrimSpace(psbtBase64),
)
if err != nil {
@ -515,7 +517,7 @@ func openChannelPsbt(ctx *cli.Context, client lnrpc.LightningClient,
verifyMsg := &lnrpc.FundingTransitionMsg{
Trigger: &lnrpc.FundingTransitionMsg_PsbtVerify{
PsbtVerify: &lnrpc.FundingPsbtVerify{
FundedPsbt: psbt,
FundedPsbt: fundedPsbt,
PendingChanId: pendingChanID[:],
},
},
@ -531,7 +533,7 @@ func openChannelPsbt(ctx *cli.Context, client lnrpc.LightningClient,
fmt.Print(userMsgSign)
// Read the signed PSBT and send it to lnd.
psbtBase64, err = readLine(quit)
finalTxStr, err := readLine(quit)
if err == io.EOF {
return nil
}
@ -539,22 +541,16 @@ func openChannelPsbt(ctx *cli.Context, client lnrpc.LightningClient,
return fmt.Errorf("reading from console "+
"failed: %v", err)
}
psbt, err = base64.StdEncoding.DecodeString(
strings.TrimSpace(psbtBase64),
finalizeMsg, err := finalizeMsgFromString(
finalTxStr, pendingChanID[:],
)
if err != nil {
return fmt.Errorf("base64 decode failed: %v",
err)
return err
}
finalizeMsg := &lnrpc.FundingTransitionMsg{
Trigger: &lnrpc.FundingTransitionMsg_PsbtFinalize{
PsbtFinalize: &lnrpc.FundingPsbtFinalize{
SignedPsbt: psbt,
PendingChanId: pendingChanID[:],
},
},
transitionMsg := &lnrpc.FundingTransitionMsg{
Trigger: finalizeMsg,
}
err = sendFundingState(ctxc, ctx, finalizeMsg)
err = sendFundingState(ctxc, ctx, transitionMsg)
if err != nil {
return fmt.Errorf("finalizing PSBT funding "+
"flow failed: %v", err)
@ -686,3 +682,41 @@ func sendFundingState(cancelCtx context.Context, cliCtx *cli.Context,
_, err := client.FundingStateStep(cancelCtx, msg)
return err
}
// finalizeMsgFromString creates the final message for the PsbtFinalize step
// from either a hex encoded raw wire transaction or a base64 encoded PSBT
// packet.
func finalizeMsgFromString(tx string,
pendingChanID []byte) (*lnrpc.FundingTransitionMsg_PsbtFinalize, error) {
rawTx, err := hex.DecodeString(strings.TrimSpace(tx))
if err == nil {
// Hex decoding succeeded so we assume we have a raw wire format
// transaction. Let's submit that instead of a PSBT packet.
tx := &wire.MsgTx{}
err := tx.Deserialize(bytes.NewReader(rawTx))
if err != nil {
return nil, fmt.Errorf("deserializing as raw wire "+
"transaction failed: %v", err)
}
return &lnrpc.FundingTransitionMsg_PsbtFinalize{
PsbtFinalize: &lnrpc.FundingPsbtFinalize{
FinalRawTx: rawTx,
PendingChanId: pendingChanID,
},
}, nil
}
// If the string isn't a hex encoded transaction, we assume it must be
// a base64 encoded PSBT packet.
psbtBytes, err := base64.StdEncoding.DecodeString(strings.TrimSpace(tx))
if err != nil {
return nil, fmt.Errorf("base64 decode failed: %v", err)
}
return &lnrpc.FundingTransitionMsg_PsbtFinalize{
PsbtFinalize: &lnrpc.FundingPsbtFinalize{
SignedPsbt: psbtBytes,
PendingChanId: pendingChanID,
},
}, nil
}