2021-02-10 16:06:01 -05:00
// Copyright (c) 2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
# ifndef BITCOIN_WALLET_SPEND_H
# define BITCOIN_WALLET_SPEND_H
2021-09-11 10:29:00 +08:00
# include <consensus/amount.h>
2021-02-10 16:06:01 -05:00
# include <wallet/coinselection.h>
# include <wallet/transaction.h>
# include <wallet/wallet.h>
2021-11-12 11:13:29 -05:00
namespace wallet {
2021-02-12 18:01:22 -05:00
/** Get the marginal bytes if spending the specified output from this transaction */
int GetTxSpendSize ( const CWallet & wallet , const CWalletTx & wtx , unsigned int out , bool use_max_sig = false ) ;
2021-02-10 16:06:01 -05:00
class COutput
{
public :
const CWalletTx * tx ;
/** Index in tx->vout. */
int i ;
/**
* Depth in block chain .
* If > 0 : the tx is on chain and has this many confirmations .
* If = 0 : the tx is waiting confirmation .
* If < 0 : a conflicting tx is on chain and has this many confirmations . */
int nDepth ;
/** Pre-computed estimated size of this output as a fully-signed input in a transaction. Can be -1 if it could not be calculated */
int nInputBytes ;
/** Whether we have the private keys to spend this output */
bool fSpendable ;
/** Whether we know how to spend this output, ignoring the lack of keys */
bool fSolvable ;
/** Whether to use the maximum sized, 72 byte signature when calculating the size of the input spend. This should only be set when watch-only outputs are allowed */
bool use_max_sig ;
/**
* Whether this output is considered safe to spend . Unconfirmed transactions
* from outside keys and unconfirmed replacement transactions are considered
* unsafe and will not be used to fund new spending transactions .
*/
bool fSafe ;
2021-02-12 18:01:22 -05:00
COutput ( const CWallet & wallet , const CWalletTx & wtx , int iIn , int nDepthIn , bool fSpendableIn , bool fSolvableIn , bool fSafeIn , bool use_max_sig_in = false )
2022-01-18 19:10:39 -05:00
: tx ( & wtx ) ,
i ( iIn ) ,
nDepth ( nDepthIn ) ,
nInputBytes ( - 1 ) ,
fSpendable ( fSpendableIn ) ,
fSolvable ( fSolvableIn ) ,
use_max_sig ( use_max_sig_in ) ,
fSafe ( fSafeIn )
2021-02-10 16:06:01 -05:00
{
// If known and signable by the given wallet, compute nInputBytes
// Failure will keep this value -1
2021-02-12 18:01:22 -05:00
if ( fSpendable ) {
nInputBytes = GetTxSpendSize ( wallet , wtx , i , use_max_sig ) ;
2021-02-10 16:06:01 -05:00
}
}
std : : string ToString ( ) const ;
inline CInputCoin GetInputCoin ( ) const
{
return CInputCoin ( tx - > tx , i , nInputBytes ) ;
}
} ;
2021-02-12 18:01:22 -05:00
//Get the marginal bytes of spending the specified output
int CalculateMaximumSignedInputSize ( const CTxOut & txout , const CWallet * pwallet , bool use_max_sig = false ) ;
2019-10-18 17:17:17 -04:00
int CalculateMaximumSignedInputSize ( const CTxOut & txout , const SigningProvider * pwallet , bool use_max_sig = false ) ;
2021-02-12 18:01:22 -05:00
struct TxSize {
int64_t vsize { - 1 } ;
int64_t weight { - 1 } ;
} ;
/** Calculate the size of the transaction assuming all signatures are max size
* Use DummySignatureCreator , which inserts 71 byte signatures everywhere .
* NOTE : this requires that all inputs must be in mapWallet ( eg the tx should
* be AllInputsMine ) . */
2019-10-18 17:17:17 -04:00
TxSize CalculateMaximumSignedTxSize ( const CTransaction & tx , const CWallet * wallet , const std : : vector < CTxOut > & txouts , const CCoinControl * coin_control = nullptr ) ;
TxSize CalculateMaximumSignedTxSize ( const CTransaction & tx , const CWallet * wallet , const CCoinControl * coin_control = nullptr ) EXCLUSIVE_LOCKS_REQUIRED ( wallet - > cs_wallet ) ;
2021-02-12 18:01:22 -05:00
/**
* populate vCoins with vector of available COutputs .
*/
void AvailableCoins ( const CWallet & wallet , std : : vector < COutput > & vCoins , const CCoinControl * coinControl = nullptr , const CAmount & nMinimumAmount = 1 , const CAmount & nMaximumAmount = MAX_MONEY , const CAmount & nMinimumSumAmount = MAX_MONEY , const uint64_t nMaximumCount = 0 ) EXCLUSIVE_LOCKS_REQUIRED ( wallet . cs_wallet ) ;
CAmount GetAvailableBalance ( const CWallet & wallet , const CCoinControl * coinControl = nullptr ) ;
/**
* Find non - change parent output .
*/
const CTxOut & FindNonChangeParentOutput ( const CWallet & wallet , const CTransaction & tx , int output ) EXCLUSIVE_LOCKS_REQUIRED ( wallet . cs_wallet ) ;
/**
* Return list of available coins and locked coins grouped by non - change output address .
*/
std : : map < CTxDestination , std : : vector < COutput > > ListCoins ( const CWallet & wallet ) EXCLUSIVE_LOCKS_REQUIRED ( wallet . cs_wallet ) ;
std : : vector < OutputGroup > GroupOutputs ( const CWallet & wallet , const std : : vector < COutput > & outputs , const CoinSelectionParams & coin_sel_params , const CoinEligibilityFilter & filter , bool positive_only ) ;
/**
2021-05-21 18:39:41 -04:00
* Attempt to find a valid input set that meets the provided eligibility filter and target .
* Multiple coin selection algorithms will be run and the input set that produces the least waste
* ( according to the waste metric ) will be chosen .
*
* param @ [ in ] wallet The wallet which provides solving data for the coins
* param @ [ in ] nTargetValue The target value
* param @ [ in ] eligilibity_filter A filter containing rules for which coins are allowed to be included in this selection
* param @ [ in ] coins The vector of coins available for selection prior to filtering
* param @ [ in ] coin_selection_params Parameters for the coin selection
* returns If successful , a SelectionResult containing the input set
* If failed , a nullopt
2021-02-12 18:01:22 -05:00
*/
2021-05-21 18:39:41 -04:00
std : : optional < SelectionResult > AttemptSelection ( const CWallet & wallet , const CAmount & nTargetValue , const CoinEligibilityFilter & eligibility_filter , std : : vector < COutput > coins ,
const CoinSelectionParams & coin_selection_params ) ;
2021-02-12 18:01:22 -05:00
/**
2021-05-21 18:55:21 -04:00
* Select a set of coins such that nTargetValue is met and at least
2021-02-12 18:01:22 -05:00
* all coins from coin_control are selected ; never select unconfirmed coins if they are not ours
2021-05-21 18:55:21 -04:00
* param @ [ in ] wallet The wallet which provides data necessary to spend the selected coins
* param @ [ in ] vAvailableCoins The vector of coins available to be spent
* param @ [ in ] nTargetValue The target value
* param @ [ in ] coin_selection_params Parameters for this coin selection such as feerates , whether to avoid partial spends ,
* and whether to subtract the fee from the outputs .
* returns If successful , a SelectionResult containing the selected coins
* If failed , a nullopt .
2021-02-12 18:01:22 -05:00
*/
2021-05-21 18:55:21 -04:00
std : : optional < SelectionResult > SelectCoins ( const CWallet & wallet , const std : : vector < COutput > & vAvailableCoins , const CAmount & nTargetValue , const CCoinControl & coin_control ,
const CoinSelectionParams & coin_selection_params ) EXCLUSIVE_LOCKS_REQUIRED ( wallet . cs_wallet ) ;
2021-02-12 18:01:22 -05:00
/**
* Create a new transaction paying the recipients with a set of coins
* selected by SelectCoins ( ) ; Also create the change output , when needed
* @ note passing nChangePosInOut as - 1 will result in setting a random position
*/
bool CreateTransaction ( CWallet & wallet , const std : : vector < CRecipient > & vecSend , CTransactionRef & tx , CAmount & nFeeRet , int & nChangePosInOut , bilingual_str & error , const CCoinControl & coin_control , FeeCalculation & fee_calc_out , bool sign = true ) ;
/**
* Insert additional inputs into the transaction by
* calling CreateTransaction ( ) ;
*/
bool FundTransaction ( CWallet & wallet , CMutableTransaction & tx , CAmount & nFeeRet , int & nChangePosInOut , bilingual_str & error , bool lockUnspents , const std : : set < int > & setSubtractFeeFromOutputs , CCoinControl ) ;
2021-11-12 11:13:29 -05:00
} // namespace wallet
2021-02-12 18:01:22 -05:00
2021-02-10 16:06:01 -05:00
# endif // BITCOIN_WALLET_SPEND_H