chanfunding: extract FinalizeRawTX into own method

As a preparation to also allow the final TX to be specified in the raw
wire format, we extract the check of the final transaction into its own
method.
This commit is contained in:
Oliver Gugger 2020-09-07 18:02:43 +02:00
parent 154dc1af66
commit d581cd02fc
No known key found for this signature in database
GPG Key ID: 8E4256593F177720

@ -125,6 +125,11 @@ type PsbtIntent struct {
// Only witness data should be added after the verification process.
PendingPsbt *psbt.Packet
// FinalTX is the final, signed and ready to be published wire format
// transaction. This is only set after the PsbtFinalize step was
// completed successfully.
FinalTX *wire.MsgTx
// PsbtReady is an error channel the funding manager will listen for
// a signal about the PSBT being ready to continue the funding flow. In
// the normal, happy flow, this channel is only ever closed. If a
@ -270,12 +275,29 @@ func (i *PsbtIntent) Finalize(packet *psbt.Packet) error {
if err != nil {
return fmt.Errorf("error finalizing PSBT: %v", err)
}
_, err = psbt.Extract(packet)
rawTx, err := psbt.Extract(packet)
if err != nil {
return fmt.Errorf("unable to extract funding TX: %v", err)
}
// Do a basic check that this is still the same PSBT that we verified in
return i.FinalizeRawTX(rawTx)
}
// FinalizeRawTX makes sure the final raw transaction that is given to the
// intent is fully valid and signed but still contains the same UTXOs and
// outputs as the pending transaction we previously verified. If everything
// checks out, the funding manager is informed that the channel can now be
// opened and the funding transaction be broadcast.
func (i *PsbtIntent) FinalizeRawTX(rawTx *wire.MsgTx) error {
if rawTx == nil {
return fmt.Errorf("raw transaction is nil")
}
if i.State != PsbtVerified {
return fmt.Errorf("invalid state. got %v expected %v", i.State,
PsbtVerified)
}
// Do a basic check that this is still the same TX that we verified in
// the previous step. This is to protect the user from unwanted
// modifications. We only check the outputs and previous outpoints of
// the inputs of the wire transaction because the fields in the PSBT
@ -283,23 +305,21 @@ func (i *PsbtIntent) Finalize(packet *psbt.Packet) error {
if i.PendingPsbt == nil {
return fmt.Errorf("PSBT was not verified first")
}
err = verifyOutputsEqual(
packet.UnsignedTx.TxOut, i.PendingPsbt.UnsignedTx.TxOut,
)
err := verifyOutputsEqual(rawTx.TxOut, i.PendingPsbt.UnsignedTx.TxOut)
if err != nil {
return fmt.Errorf("outputs differ from verified PSBT: %v", err)
}
err = verifyInputPrevOutpointsEqual(
packet.UnsignedTx.TxIn, i.PendingPsbt.UnsignedTx.TxIn,
rawTx.TxIn, i.PendingPsbt.UnsignedTx.TxIn,
)
if err != nil {
return fmt.Errorf("inputs differ from verified PSBT: %v", err)
}
// As far as we can tell, this PSBT is ok to be used as a funding
// As far as we can tell, this TX is ok to be used as a funding
// transaction.
i.PendingPsbt = packet
i.State = PsbtFinalized
i.FinalTX = rawTx
// Signal the funding manager that it can now finally continue with its
// funding flow as the PSBT is now ready to be converted into a real
@ -319,32 +339,22 @@ func (i *PsbtIntent) CompileFundingTx() (*wire.MsgTx, error) {
i.State, PsbtFinalized)
}
// Make sure the PSBT can be finalized and extracted.
err := psbt.MaybeFinalizeAll(i.PendingPsbt)
if err != nil {
return nil, fmt.Errorf("error finalizing PSBT: %v", err)
}
fundingTx, err := psbt.Extract(i.PendingPsbt)
if err != nil {
return nil, fmt.Errorf("unable to extract funding TX: %v", err)
}
// Identify our funding outpoint now that we know everything's ready.
_, txOut, err := i.FundingOutput()
if err != nil {
return nil, fmt.Errorf("cannot get funding output: %v", err)
}
ok, idx := input.FindScriptOutputIndex(fundingTx, txOut.PkScript)
ok, idx := input.FindScriptOutputIndex(i.FinalTX, txOut.PkScript)
if !ok {
return nil, fmt.Errorf("funding output not found in PSBT")
}
i.chanPoint = &wire.OutPoint{
Hash: fundingTx.TxHash(),
Hash: i.FinalTX.TxHash(),
Index: idx,
}
i.State = PsbtFundingTxCompiled
return fundingTx, nil
return i.FinalTX, nil
}
// RemoteCanceled informs the listener of the PSBT ready channel that the