From 43599deab57f0876257302f312a5381efb31d0b7 Mon Sep 17 00:00:00 2001 From: ziggie Date: Mon, 13 Feb 2023 14:25:09 +0100 Subject: [PATCH] cmd: new input selection changes are adopted. The new NewUnsignedTransaction function requires different input values. Now a constant input slice and the input selection strategy is needed. --- cmd/sweepaccount/main.go | 60 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/cmd/sweepaccount/main.go b/cmd/sweepaccount/main.go index 85284931f1..b8c0f395e0 100644 --- a/cmd/sweepaccount/main.go +++ b/cmd/sweepaccount/main.go @@ -22,6 +22,7 @@ import ( "github.com/btcsuite/btcwallet/wallet/txauthor" "github.com/btcsuite/btcwallet/wallet/txrules" "github.com/btcsuite/btcwallet/wallet/txsizes" + "github.com/btcsuite/btcwallet/wtxmgr" "github.com/jessevdk/go-flags" ) @@ -187,6 +188,56 @@ func makeInputSource(outputs []btcjson.ListUnspentResult) txauthor.InputSource { } } +// fetchInputs fetches every unspent output with non-zero output values. +func fetchInputs(outputs []btcjson.ListUnspentResult) ([]wtxmgr.Credit, error) { + var ( + totalInputValue btcutil.Amount + inputs = make([]wtxmgr.Credit, 0, len(outputs)) + sourceErr error + ) + for _, output := range outputs { + output := output + + outputAmount, err := btcutil.NewAmount(output.Amount) + if err != nil { + sourceErr = fmt.Errorf( + "invalid amount `%v` in listunspent result", + output.Amount) + break + } + if outputAmount == 0 { + continue + } + if !saneOutputValue(outputAmount) { + sourceErr = fmt.Errorf( + "impossible output amount `%v` in listunspent result", + outputAmount) + break + } + totalInputValue += outputAmount + + previousOutPoint, err := parseOutPoint(&output) + if err != nil { + sourceErr = fmt.Errorf( + "invalid data in listunspent result: %v", + err) + break + } + + inputs = append(inputs, wtxmgr.Credit{ + OutPoint: previousOutPoint, + Amount: outputAmount, + }) + } + + if sourceErr == nil && totalInputValue == 0 { + sourceErr = noInputValue{} + } + + return inputs, sourceErr + +} + // makeDestinationScriptSource creates a ChangeSource which is used to receive // all correlated previous input value. A non-change address is created by this // function. @@ -277,10 +328,15 @@ func sweep() error { numErrors++ } for _, previousOutputs := range sourceOutputs { - inputSource := makeInputSource(previousOutputs) + // inputSource := makeInputSource(previousOutputs) + inputs, err := fetchInputs(previousOutputs) + if err != nil { + return err + } destinationSource := makeDestinationScriptSource(rpcClient, opts.DestinationAccount) + // We are only selecting postive yieling outputs. tx, err := txauthor.NewUnsignedTransaction(nil, opts.FeeRate.Amount, - inputSource, destinationSource) + inputs, txauthor.PositiveYieldingSelection, destinationSource) if err != nil { if err != (noInputValue{}) { reportError("Failed to create unsigned transaction: %v", err)