sweep/txgenerator: fix input witness ordering

This commit fixes an issue that would arise if inputs without required
TxOuts would be swept together with inputs with required TxOuts. In this
case we would add the required ones first to the transaction, but did
not change the order we signed the inputs, resulting in signing the
wrong input index.
This commit is contained in:
Johan T. Halseth 2020-12-07 09:34:13 +01:00
parent 669663bfc2
commit 84ee6b6b86
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26

View File

@ -137,28 +137,35 @@ func createSweepTx(inputs []input.Input, outputPkScript []byte,
dustLimit btcutil.Amount, signer input.Signer) (*wire.MsgTx, error) { dustLimit btcutil.Amount, signer input.Signer) (*wire.MsgTx, error) {
inputs, estimator := getWeightEstimate(inputs, feePerKw) inputs, estimator := getWeightEstimate(inputs, feePerKw)
txFee := estimator.fee() txFee := estimator.fee()
// Create the sweep transaction that we will be building. We use var (
// version 2 as it is required for CSV. // Create the sweep transaction that we will be building. We
sweepTx := wire.NewMsgTx(2) // use version 2 as it is required for CSV.
sweepTx = wire.NewMsgTx(2)
// Track whether any of the inputs require a certain locktime. // Track whether any of the inputs require a certain locktime.
locktime := int32(-1) locktime = int32(-1)
// We keep track of total input amount, and required output
// amount to use for calculating the change amount below.
totalInput btcutil.Amount
requiredOutput btcutil.Amount
// We'll add the inputs as we go so we know the final ordering
// of inputs to sign.
idxs []input.Input
)
// We start by adding all inputs that commit to an output. We do this // We start by adding all inputs that commit to an output. We do this
// since the input and output index must stay the same for the // since the input and output index must stay the same for the
// signatures to be valid. // signatures to be valid.
var (
totalInput btcutil.Amount
requiredOutput btcutil.Amount
)
for _, o := range inputs { for _, o := range inputs {
if o.RequiredTxOut() == nil { if o.RequiredTxOut() == nil {
continue continue
} }
idxs = append(idxs, o)
sweepTx.AddTxIn(&wire.TxIn{ sweepTx.AddTxIn(&wire.TxIn{
PreviousOutPoint: *o.OutPoint(), PreviousOutPoint: *o.OutPoint(),
Sequence: o.BlocksToMaturity(), Sequence: o.BlocksToMaturity(),
@ -186,6 +193,7 @@ func createSweepTx(inputs []input.Input, outputPkScript []byte,
continue continue
} }
idxs = append(idxs, o)
sweepTx.AddTxIn(&wire.TxIn{ sweepTx.AddTxIn(&wire.TxIn{
PreviousOutPoint: *o.OutPoint(), PreviousOutPoint: *o.OutPoint(),
Sequence: o.BlocksToMaturity(), Sequence: o.BlocksToMaturity(),
@ -255,10 +263,8 @@ func createSweepTx(inputs []input.Input, outputPkScript []byte,
return nil return nil
} }
// Finally we'll attach a valid input script to each csv and cltv input for idx, inp := range idxs {
// within the sweeping transaction. if err := addInputScript(idx, inp); err != nil {
for i, input := range inputs {
if err := addInputScript(i, input); err != nil {
return nil, err return nil, err
} }
} }