lnwallet+rpcserver: allow final raw tx to be specified

With this commit we allow the final transaction of a PSBT funding flow
to also be specified as a raw wire format transaction.
This commit is contained in:
Oliver Gugger 2020-09-07 18:02:46 +02:00
parent 1c832cbce7
commit 5375f88b55
No known key found for this signature in database
GPG Key ID: 8E4256593F177720
2 changed files with 56 additions and 11 deletions

View File

@ -536,8 +536,8 @@ func (l *LightningWallet) PsbtFundingVerify(pid [32]byte,
// PsbtFundingFinalize looks up a previously registered funding intent by its
// pending channel ID and tries to advance the state machine by finalizing the
// passed PSBT.
func (l *LightningWallet) PsbtFundingFinalize(pid [32]byte,
packet *psbt.Packet) error {
func (l *LightningWallet) PsbtFundingFinalize(pid [32]byte, packet *psbt.Packet,
rawTx *wire.MsgTx) error {
l.intentMtx.Lock()
defer l.intentMtx.Unlock()
@ -551,9 +551,23 @@ func (l *LightningWallet) PsbtFundingFinalize(pid [32]byte,
if !ok {
return fmt.Errorf("incompatible funding intent")
}
err := psbtIntent.Finalize(packet)
if err != nil {
return fmt.Errorf("error finalizing PSBT: %v", err)
// Either the PSBT or the raw TX must be set.
switch {
case packet != nil && rawTx == nil:
err := psbtIntent.Finalize(packet)
if err != nil {
return fmt.Errorf("error finalizing PSBT: %v", err)
}
case rawTx != nil && packet == nil:
err := psbtIntent.FinalizeRawTX(rawTx)
if err != nil {
return fmt.Errorf("error finalizing raw TX: %v", err)
}
default:
return fmt.Errorf("either a PSBT or raw TX must be specified")
}
return nil

View File

@ -6738,19 +6738,50 @@ func (r *rpcServer) FundingStateStep(ctx context.Context,
// the final PSBT to the previously verified one and if nothing
// unexpected was changed, continue the channel opening process.
case in.GetPsbtFinalize() != nil:
msg := in.GetPsbtFinalize()
rpcsLog.Debugf("Finalizing PSBT for pending_id=%x",
in.GetPsbtFinalize().PendingChanId)
msg.PendingChanId)
copy(pendingChanID[:], in.GetPsbtFinalize().PendingChanId)
packet, err := psbt.NewFromRawBytes(
bytes.NewReader(in.GetPsbtFinalize().SignedPsbt), false,
var (
packet *psbt.Packet
rawTx *wire.MsgTx
err error
)
if err != nil {
return nil, fmt.Errorf("error parsing psbt: %v", err)
// Either the signed PSBT or the raw transaction need to be set
// but not both at the same time.
switch {
case len(msg.SignedPsbt) > 0 && len(msg.FinalRawTx) > 0:
return nil, fmt.Errorf("cannot set both signed PSBT " +
"and final raw TX at the same time")
case len(msg.SignedPsbt) > 0:
packet, err = psbt.NewFromRawBytes(
bytes.NewReader(in.GetPsbtFinalize().SignedPsbt),
false,
)
if err != nil {
return nil, fmt.Errorf("error parsing psbt: %v",
err)
}
case len(msg.FinalRawTx) > 0:
rawTx = &wire.MsgTx{}
err = rawTx.Deserialize(bytes.NewReader(msg.FinalRawTx))
if err != nil {
return nil, fmt.Errorf("error parsing final "+
"raw TX: %v", err)
}
default:
return nil, fmt.Errorf("PSBT or raw transaction to " +
"finalize missing")
}
err = r.server.cc.wallet.PsbtFundingFinalize(
pendingChanID, packet,
pendingChanID, packet, rawTx,
)
if err != nil {
return nil, err