multi: use prev output fetcher where possible

This commit is contained in:
Oliver Gugger
2022-03-18 18:37:44 +01:00
parent 72c9582b85
commit f130eddb92
13 changed files with 255 additions and 44 deletions

View File

@@ -2,6 +2,7 @@ package lookout
import (
"errors"
"fmt"
"github.com/btcsuite/btcd/blockchain"
"github.com/btcsuite/btcd/btcec/v2"
@@ -177,11 +178,11 @@ func (p *JusticeDescriptor) assembleJusticeTxn(txWeight int64,
// First, construct add the breached inputs to our justice transaction
// and compute the total amount that will be swept.
var totalAmt btcutil.Amount
for _, input := range inputs {
totalAmt += btcutil.Amount(input.txOut.Value)
for _, inp := range inputs {
totalAmt += btcutil.Amount(inp.txOut.Value)
justiceTxn.AddTxIn(&wire.TxIn{
PreviousOutPoint: input.outPoint,
Sequence: input.sequence,
PreviousOutPoint: inp.outPoint,
Sequence: inp.sequence,
})
}
@@ -217,20 +218,22 @@ func (p *JusticeDescriptor) assembleJusticeTxn(txWeight int64,
}
// Attach each of the provided witnesses to the transaction.
for _, input := range inputs {
prevOutFetcher, err := prevOutFetcher(inputs)
if err != nil {
return nil, fmt.Errorf("error creating previous output "+
"fetcher: %v", err)
}
for _, inp := range inputs {
// Lookup the input's new post-sort position.
i := inputIndex[input.outPoint]
justiceTxn.TxIn[i].Witness = input.witness
i := inputIndex[inp.outPoint]
justiceTxn.TxIn[i].Witness = inp.witness
// Validate the reconstructed witnesses to ensure they are valid
// for the breached inputs.
vm, err := txscript.NewEngine(
input.txOut.PkScript, justiceTxn, i,
inp.txOut.PkScript, justiceTxn, i,
txscript.StandardVerifyFlags,
nil, nil, input.txOut.Value,
txscript.NewCannedPrevOutputFetcher(
input.txOut.PkScript, input.txOut.Value,
),
nil, nil, inp.txOut.Value, prevOutFetcher,
)
if err != nil {
return nil, err
@@ -345,3 +348,20 @@ func buildWitness(witnessStack [][]byte, witnessScript []byte) [][]byte {
return witness
}
// prevOutFetcher returns a txscript.MultiPrevOutFetcher for the given set
// of inputs.
func prevOutFetcher(inputs []*breachedInput) (*txscript.MultiPrevOutFetcher,
error) {
fetcher := txscript.NewMultiPrevOutFetcher(nil)
for _, inp := range inputs {
if inp.txOut == nil {
return nil, fmt.Errorf("missing input utxo information")
}
fetcher.AddPrevOut(inp.outPoint, inp.txOut)
}
return fetcher, nil
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/btcutil/txsort"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input"
@@ -262,10 +263,14 @@ func (t *backupTask) craftSessionPayload(
// information. This will either be contain both the to-local and
// to-remote outputs, or only be the to-local output.
inputs := t.inputs()
for prevOutPoint, input := range inputs {
prevOutputFetcher := txscript.NewMultiPrevOutFetcher(nil)
for prevOutPoint, inp := range inputs {
prevOutputFetcher.AddPrevOut(
prevOutPoint, inp.SignDesc().Output,
)
justiceTxn.AddTxIn(&wire.TxIn{
PreviousOutPoint: prevOutPoint,
Sequence: input.BlocksToMaturity(),
Sequence: inp.BlocksToMaturity(),
})
}
@@ -284,7 +289,7 @@ func (t *backupTask) craftSessionPayload(
}
// Construct a sighash cache to improve signing performance.
hashCache := input.NewTxSigHashesV0Only(justiceTxn)
hashCache := txscript.NewTxSigHashes(justiceTxn, prevOutputFetcher)
// Since the transaction inputs could have been reordered as a result of
// the BIP69 sort, create an index mapping each prevout to it's new
@@ -303,7 +308,7 @@ func (t *backupTask) craftSessionPayload(
// Construct the full witness required to spend this input.
inputScript, err := inp.CraftInputScript(
signer, justiceTxn, hashCache, i,
signer, justiceTxn, hashCache, prevOutputFetcher, i,
)
if err != nil {
return hint, nil, err