2011-08-09 07:27:58 -04:00
// Copyright (c) 2009-2010 Satoshi Nakamoto
2020-01-14 16:17:38 -03:00
// Copyright (c) 2009-2020 The Bitcoin Core developers
2014-10-26 04:03:12 -03:00
// Distributed under the MIT software license, see the accompanying
2012-05-18 10:02:28 -04:00
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2014-08-28 16:21:03 -04:00
2015-03-21 14:15:31 -03:00
# ifndef BITCOIN_WALLET_WALLET_H
# define BITCOIN_WALLET_WALLET_H
2011-06-26 13:23:24 -04:00
2017-11-09 21:57:53 -03:00
# include <amount.h>
2017-07-31 15:30:21 -04:00
# include <interfaces/chain.h>
2017-07-30 16:00:56 -04:00
# include <interfaces/handler.h>
2018-07-09 04:15:50 -04:00
# include <outputtype.h>
2017-11-09 21:57:53 -03:00
# include <policy/feerate.h>
2020-02-10 21:50:56 -03:00
# include <psbt.h>
2017-11-09 21:57:53 -03:00
# include <tinyformat.h>
2020-02-13 19:09:12 -03:00
# include <util/message.h>
2018-10-22 19:51:11 -03:00
# include <util/strencodings.h>
2020-03-27 11:06:14 -03:00
# include <util/string.h>
2018-10-22 19:51:11 -03:00
# include <util/system.h>
2020-06-19 18:07:18 -04:00
# include <util/ui_change_type.h>
2019-04-17 13:27:02 -04:00
# include <validationinterface.h>
2018-03-07 14:18:37 -03:00
# include <wallet/coinselection.h>
2019-04-17 13:27:02 -04:00
# include <wallet/crypter.h>
2019-10-07 15:11:34 -03:00
# include <wallet/scriptpubkeyman.h>
2017-11-09 21:57:53 -03:00
# include <wallet/walletdb.h>
2018-09-28 12:50:18 -03:00
# include <wallet/walletutil.h>
2013-04-13 02:13:08 -03:00
# include <algorithm>
2016-09-09 05:15:01 -03:00
# include <atomic>
2013-04-13 02:13:08 -03:00
# include <map>
2018-04-02 15:31:40 -03:00
# include <memory>
2013-04-13 02:13:08 -03:00
# include <set>
# include <stdexcept>
# include <stdint.h>
# include <string>
# include <utility>
# include <vector>
2011-06-26 13:23:24 -04:00
2019-06-06 17:58:21 -04:00
# include <boost/signals2/signal.hpp>
2019-09-27 08:31:44 -03:00
using LoadWalletFn = std : : function < void ( std : : unique_ptr < interfaces : : Wallet > wallet ) > ;
2019-08-19 18:12:35 -04:00
struct bilingual_str ;
2018-12-12 20:21:19 -03:00
//! Explicitly unload and delete the wallet.
2019-01-25 00:44:54 -03:00
//! Blocks the current thread after signaling the unload intent so that all
//! wallet clients release the wallet.
//! Note that, when blocking is not required, the wallet is implicitly unloaded
//! by the shared pointer deleter.
2018-12-12 20:21:19 -03:00
void UnloadWallet ( std : : shared_ptr < CWallet > & & wallet ) ;
2018-05-22 11:18:07 -04:00
bool AddWallet ( const std : : shared_ptr < CWallet > & wallet ) ;
2020-08-17 15:21:50 -04:00
bool RemoveWallet ( const std : : shared_ptr < CWallet > & wallet , Optional < bool > load_on_start , std : : vector < bilingual_str > & warnings ) ;
bool RemoveWallet ( const std : : shared_ptr < CWallet > & wallet , Optional < bool > load_on_start ) ;
2018-05-22 11:18:07 -04:00
std : : vector < std : : shared_ptr < CWallet > > GetWallets ( ) ;
std : : shared_ptr < CWallet > GetWallet ( const std : : string & name ) ;
2020-08-04 17:55:13 -04:00
std : : shared_ptr < CWallet > LoadWallet ( interfaces : : Chain & chain , const std : : string & name , Optional < bool > load_on_start , const DatabaseOptions & options , DatabaseStatus & status , bilingual_str & error , std : : vector < bilingual_str > & warnings ) ;
std : : shared_ptr < CWallet > CreateWallet ( interfaces : : Chain & chain , const std : : string & name , Optional < bool > load_on_start , const DatabaseOptions & options , DatabaseStatus & status , bilingual_str & error , std : : vector < bilingual_str > & warnings ) ;
2019-09-27 08:31:44 -03:00
std : : unique_ptr < interfaces : : Handler > HandleLoadWallet ( LoadWalletFn load_wallet ) ;
2020-08-04 19:33:37 -04:00
std : : unique_ptr < WalletDatabase > MakeWalletDatabase ( const std : : string & name , const DatabaseOptions & options , DatabaseStatus & status , bilingual_str & error ) ;
2016-03-15 06:30:37 -03:00
2014-10-26 04:03:12 -03:00
//! -paytxfee default
2018-04-07 13:12:46 -03:00
constexpr CAmount DEFAULT_PAY_TX_FEE = 0 ;
2016-01-05 15:11:34 -03:00
//! -fallbackfee default
2019-08-01 16:39:46 -04:00
static const CAmount DEFAULT_FALLBACK_FEE = 0 ;
2018-04-07 13:12:46 -03:00
//! -discardfee default
2017-07-06 14:00:46 -04:00
static const CAmount DEFAULT_DISCARD_FEE = 10000 ;
2015-09-13 18:23:59 -03:00
//! -mintxfee default
static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000 ;
2018-10-25 21:36:56 -03:00
/**
* maximum fee increase allowed to do partial spend avoidance , even for nodes with this feature disabled by default
*
* A value of - 1 disables this feature completely .
* A value of 0 ( current default ) means to attempt to do partial spend avoidance , and use its results if the fees remain * unchanged *
* A value > 0 means to do partial spend avoidance if the fee difference against a regular coin selection instance is in the range [ 0. . value ] .
*/
static const CAmount DEFAULT_MAX_AVOIDPARTIALSPEND_FEE = 0 ;
//! discourage APS fee higher than this amount
constexpr CAmount HIGH_APS_FEE { COIN / 10000 } ;
2017-01-23 15:15:24 -03:00
//! minimum recommended increment for BIP 125 replacement txs
static const CAmount WALLET_INCREMENTAL_RELAY_FEE = 5000 ;
2015-11-09 15:16:38 -03:00
//! Default for -spendzeroconfchange
static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true ;
2016-12-02 17:29:20 -03:00
//! Default for -walletrejectlongchains
static const bool DEFAULT_WALLET_REJECT_LONG_CHAINS = false ;
2015-05-18 03:51:16 -03:00
//! -txconfirmtarget default
2016-10-28 09:15:46 -03:00
static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 6 ;
2016-09-01 10:24:45 -03:00
//! -walletrbf default
static const bool DEFAULT_WALLET_RBF = false ;
2015-06-27 16:21:41 -03:00
static const bool DEFAULT_WALLETBROADCAST = true ;
2016-09-21 07:15:18 -03:00
static const bool DEFAULT_DISABLE_WALLET = false ;
2019-02-20 15:45:16 -03:00
//! -maxtxfee default
constexpr CAmount DEFAULT_TRANSACTION_MAXFEE { COIN / 10 } ;
//! Discourage users to set fees higher than this amount (in satoshis) per kB
constexpr CAmount HIGH_TX_FEE_PER_KB { COIN / 100 } ;
//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis)
constexpr CAmount HIGH_MAX_TX_FEE { 100 * HIGH_TX_FEE_PER_KB } ;
2016-01-02 08:34:08 -03:00
2018-10-03 02:41:03 -03:00
//! Pre-calculated constants for input size estimation in *virtual size*
static constexpr size_t DUMMY_NESTED_P2WPKH_INPUT_SIZE = 91 ;
2013-11-16 13:37:31 -03:00
class CCoinControl ;
2012-02-27 09:19:32 -03:00
class COutput ;
2013-04-13 02:13:08 -03:00
class CScript ;
class CWalletTx ;
2017-06-15 08:43:44 -04:00
struct FeeCalculation ;
2017-06-13 11:28:30 -04:00
enum class FeeEstimateMode ;
2019-06-18 15:48:20 -04:00
class ReserveDestination ;
2011-06-26 13:23:24 -04:00
2018-02-10 23:06:35 -03:00
//! Default for -addresstype
2019-09-18 10:25:23 -03:00
constexpr OutputType DEFAULT_ADDRESS_TYPE { OutputType : : BECH32 } ;
2017-11-30 21:49:11 -03:00
2018-07-25 03:24:55 -04:00
static constexpr uint64_t KNOWN_WALLET_FLAGS =
WALLET_FLAG_AVOID_REUSE
| WALLET_FLAG_BLANK_WALLET
| WALLET_FLAG_KEY_ORIGIN_METADATA
2019-07-05 22:32:59 -04:00
| WALLET_FLAG_DISABLE_PRIVATE_KEYS
| WALLET_FLAG_DESCRIPTORS ;
2018-07-25 03:24:55 -04:00
2018-09-13 01:35:10 -03:00
static constexpr uint64_t MUTABLE_WALLET_FLAGS =
WALLET_FLAG_AVOID_REUSE ;
2018-07-25 03:24:55 -04:00
static const std : : map < std : : string , WalletFlags > WALLET_FLAG_MAP {
{ " avoid_reuse " , WALLET_FLAG_AVOID_REUSE } ,
{ " blank " , WALLET_FLAG_BLANK_WALLET } ,
{ " key_origin_metadata " , WALLET_FLAG_KEY_ORIGIN_METADATA } ,
{ " disable_private_keys " , WALLET_FLAG_DISABLE_PRIVATE_KEYS } ,
2019-07-05 22:32:59 -04:00
{ " descriptor_wallet " , WALLET_FLAG_DESCRIPTORS } ,
2018-07-25 03:24:55 -04:00
} ;
extern const std : : map < uint64_t , std : : string > WALLET_FLAG_CAVEATS ;
2017-05-05 03:53:39 -03:00
2019-06-18 15:48:20 -04:00
/** A wrapper to reserve an address from a wallet
2019-04-09 14:36:57 -04:00
*
2019-07-10 11:37:45 -04:00
* ReserveDestination is used to reserve an address .
* It is currently only used inside of CreateTransaction .
2019-04-09 14:36:57 -04:00
*
2019-06-18 15:48:20 -04:00
* Instantiating a ReserveDestination does not reserve an address . To do so ,
* GetReservedDestination ( ) needs to be called on the object . Once an address has been
* reserved , call KeepDestination ( ) on the ReserveDestination object to make sure it is not
* returned . Call ReturnDestination ( ) to return the address so it can be re - used ( for
* example , if the address was used in a new transaction
2019-04-09 14:36:57 -04:00
* and that transaction was not completed and needed to be aborted ) .
*
2019-06-18 15:48:20 -04:00
* If an address is reserved and KeepDestination ( ) is not called , then the address will be
* returned when the ReserveDestination goes out of scope .
2019-04-09 14:36:57 -04:00
*/
2019-06-18 15:48:20 -04:00
class ReserveDestination
2019-04-09 13:13:03 -04:00
{
protected :
2019-06-18 15:48:20 -04:00
//! The wallet to reserve from
2020-03-02 05:21:38 -03:00
const CWallet * const pwallet ;
2019-10-07 15:11:34 -03:00
//! The ScriptPubKeyMan to reserve from. Based on type when GetReservedDestination is called
ScriptPubKeyMan * m_spk_man { nullptr } ;
2019-10-24 05:44:20 -03:00
OutputType const type ;
2019-06-18 15:48:20 -04:00
//! The index of the address's key in the keypool
2019-04-09 13:13:03 -04:00
int64_t nIndex { - 1 } ;
2019-06-18 15:48:20 -04:00
//! The destination
CTxDestination address ;
2019-04-09 14:36:57 -04:00
//! Whether this is from the internal (change output) keypool
2019-04-09 13:13:03 -04:00
bool fInternal { false } ;
public :
2019-06-18 15:48:20 -04:00
//! Construct a ReserveDestination object. This does NOT reserve an address yet
2019-10-24 05:44:20 -03:00
explicit ReserveDestination ( CWallet * pwallet , OutputType type )
: pwallet ( pwallet )
, type ( type ) { }
2019-04-09 13:13:03 -04:00
2019-06-18 15:48:20 -04:00
ReserveDestination ( const ReserveDestination & ) = delete ;
ReserveDestination & operator = ( const ReserveDestination & ) = delete ;
2019-04-09 13:13:03 -04:00
2019-04-09 14:36:57 -04:00
//! Destructor. If a key has been reserved and not KeepKey'ed, it will be returned to the keypool
2019-06-18 15:48:20 -04:00
~ ReserveDestination ( )
2019-04-09 13:13:03 -04:00
{
2019-06-18 15:48:20 -04:00
ReturnDestination ( ) ;
2019-04-09 13:13:03 -04:00
}
2019-06-18 15:48:20 -04:00
//! Reserve an address
2019-10-24 05:44:20 -03:00
bool GetReservedDestination ( CTxDestination & pubkey , bool internal ) ;
2019-06-18 15:48:20 -04:00
//! Return reserved address
void ReturnDestination ( ) ;
//! Keep the address. Do not return it's key to the keypool when this object goes out of scope
void KeepDestination ( ) ;
2019-04-09 13:13:03 -04:00
} ;
2013-07-15 01:20:50 -04:00
/** Address book data */
class CAddressBookData
{
2020-02-21 22:52:47 -03:00
private :
2020-02-21 23:04:27 -03:00
bool m_change { true } ;
2020-02-21 22:52:47 -03:00
std : : string m_label ;
2013-07-15 01:20:50 -04:00
public :
2013-07-22 02:50:39 -04:00
std : : string purpose ;
2013-07-15 01:20:50 -04:00
2020-04-03 00:02:16 -03:00
CAddressBookData ( ) : purpose ( " unknown " ) { }
2013-11-18 12:55:54 -03:00
typedef std : : map < std : : string , std : : string > StringMap ;
StringMap destdata ;
2020-02-21 22:52:47 -03:00
2020-02-21 23:04:27 -03:00
bool IsChange ( ) const { return m_change ; }
2020-04-03 00:02:16 -03:00
const std : : string & GetLabel ( ) const { return m_label ; }
2020-02-21 22:52:47 -03:00
void SetLabel ( const std : : string & label ) {
2020-02-21 23:04:27 -03:00
m_change = false ;
2020-02-21 22:52:47 -03:00
m_label = label ;
}
2013-07-15 01:20:50 -04:00
} ;
2014-07-23 08:34:36 -04:00
struct CRecipient
{
CScript scriptPubKey ;
CAmount nAmount ;
bool fSubtractFeeFromAmount ;
} ;
2014-12-18 22:03:51 -03:00
typedef std : : map < std : : string , std : : string > mapValue_t ;
2016-11-02 21:29:16 -03:00
static inline void ReadOrderPos ( int64_t & nOrderPos , mapValue_t & mapValue )
2014-12-18 22:03:51 -03:00
{
if ( ! mapValue . count ( " n " ) )
{
nOrderPos = - 1 ; // TODO: calculate elsewhere
return ;
}
2020-08-17 11:34:06 -04:00
nOrderPos = atoi64 ( mapValue [ " n " ] ) ;
2014-12-18 22:03:51 -03:00
}
2016-11-02 21:29:16 -03:00
static inline void WriteOrderPos ( const int64_t & nOrderPos , mapValue_t & mapValue )
2014-12-18 22:03:51 -03:00
{
if ( nOrderPos = = - 1 )
return ;
2020-03-27 11:06:14 -03:00
mapValue [ " n " ] = ToString ( nOrderPos ) ;
2014-12-18 22:03:51 -03:00
}
struct COutputEntry
{
CTxDestination destination ;
CAmount amount ;
int vout ;
} ;
2019-07-25 10:42:34 -04:00
/** Legacy class used for deserializing vtxPrev for backwards compatibility.
* vtxPrev was removed in commit 93 a18a3650292afbb441a47d1fa1b94aeb0164e3 ,
* but old wallet . dat files may still contain vtxPrev vectors of CMerkleTxs .
* These need to get deserialized for field alignment when deserializing
* a CWalletTx , but the deserialized values are discarded . * */
2016-11-11 21:54:51 -03:00
class CMerkleTx
2011-06-26 13:23:24 -04:00
{
2014-12-18 22:03:51 -03:00
public :
2019-07-24 14:09:28 -04:00
template < typename Stream >
void Unserialize ( Stream & s )
{
2019-07-25 10:43:54 -04:00
CTransactionRef tx ;
uint256 hashBlock ;
2019-07-24 14:09:28 -04:00
std : : vector < uint256 > vMerkleBranch ;
2019-07-25 10:43:54 -04:00
int nIndex ;
2014-12-18 22:03:51 -03:00
2019-07-24 14:09:28 -04:00
s > > tx > > hashBlock > > vMerkleBranch > > nIndex ;
}
2014-12-18 22:03:51 -03:00
} ;
2011-08-26 15:37:23 -03:00
2018-03-05 18:37:24 -03:00
//Get the marginal bytes of spending the specified output
2018-08-07 19:59:53 -04:00
int CalculateMaximumSignedInputSize ( const CTxOut & txout , const CWallet * pwallet , bool use_max_sig = false ) ;
2018-03-05 18:37:24 -03:00
2018-04-17 14:22:23 -03:00
/**
2014-12-18 22:03:51 -03:00
* A transaction with a bunch of additional info that only the owner cares about .
* It includes any unrecorded transactions needed to link it back to the block chain .
*/
2019-07-25 10:43:54 -04:00
class CWalletTx
2014-12-18 22:03:51 -03:00
{
private :
2020-08-20 20:05:40 -04:00
const CWallet * const pwallet ;
2011-06-26 13:23:24 -04:00
2019-08-12 18:12:12 -04:00
/** Constant used in hashBlock to indicate tx has been abandoned, only used at
* serialization / deserialization to avoid ambiguity with conflicted .
*/
2020-09-26 03:41:10 -03:00
static constexpr const uint256 & ABANDON_HASH = uint256 : : ONE ;
2019-07-25 10:42:34 -04:00
2014-12-18 22:03:51 -03:00
public :
2016-12-12 13:40:00 -03:00
/**
* Key / value map with information about the transaction .
*
* The following keys can be read and written through the map and are
* serialized in the wallet database :
*
* " comment " , " to " - comment strings provided to sendtoaddress ,
2018-07-27 17:05:24 -04:00
* and sendmany wallet RPCs
2017-01-25 15:13:56 -03:00
* " replaces_txid " - txid ( as HexStr ) of transaction replaced by
* bumpfee on transaction created by bumpfee
* " replaced_by_txid " - txid ( as HexStr ) of transaction created by
* bumpfee on transaction replaced by bumpfee
2016-12-12 13:40:00 -03:00
* " from " , " message " - obsolete fields that could be set in UI prior to
* 2011 ( removed in commit 4 d9b223 )
*
* The following keys are serialized in the wallet database , but shouldn ' t
* be read or written through the map ( they will be temporarily added and
* removed from the map during serialization ) :
*
* " fromaccount " - serialized strFromAccount value
* " n " - serialized nOrderPos value
* " timesmart " - serialized nTimeSmart value
* " spent " - serialized vfSpent value that existed prior to
* 2014 ( removed in commit 93 a18a3 )
*/
2014-12-18 22:03:51 -03:00
mapValue_t mapValue ;
std : : vector < std : : pair < std : : string , std : : string > > vOrderForm ;
unsigned int fTimeReceivedIsTxTime ;
2016-04-03 06:49:36 -03:00
unsigned int nTimeReceived ; //!< time received by this node
2016-12-19 12:51:45 -03:00
/**
* Stable timestamp that never changes , and reflects the order a transaction
* was added to the wallet . Timestamp is based on the block time for a
* transaction added as part of a block , or else the time when the
* transaction was received if it wasn ' t part of a block , with the timestamp
* adjusted in both cases so timestamp order matches the order transactions
* were added to the wallet . More details can be found in
* CWallet : : ComputeTimeSmart ( ) .
*/
2014-12-18 22:03:51 -03:00
unsigned int nTimeSmart ;
2016-12-15 17:14:02 -03:00
/**
* From me flag is set to 1 for transactions that were created by the wallet
* on this bitcoin node , and set to 0 for transactions that were created
* externally and came in through the network or sendrawtransaction RPC .
*/
2019-08-08 19:18:30 -04:00
bool fFromMe ;
2016-04-03 06:49:36 -03:00
int64_t nOrderPos ; //!< position in ordered transaction list
2018-07-31 12:23:26 -04:00
std : : multimap < int64_t , CWalletTx * > : : const_iterator m_it_wtxOrdered ;
2012-02-18 10:55:02 -03:00
2014-12-18 22:03:51 -03:00
// memory only
2019-04-09 22:40:35 -04:00
enum AmountType { DEBIT , CREDIT , IMMATURE_CREDIT , AVAILABLE_CREDIT , AMOUNTTYPE_ENUM_ELEMENTS } ;
CAmount GetCachableAmount ( AmountType type , const isminefilter & filter , bool recalculate = false ) const ;
mutable CachableAmount m_amounts [ AMOUNTTYPE_ENUM_ELEMENTS ] ;
2020-01-07 10:47:20 -03:00
/**
* This flag is true if all m_amounts caches are empty . This is particularly
* useful in places where MarkDirty is conditionally called and the
* condition can be expensive and thus can be skipped if the flag is true .
* See MarkDestinationsDirty .
*/
mutable bool m_is_cache_empty { true } ;
2014-12-18 22:03:51 -03:00
mutable bool fChangeCached ;
Use callbacks to cache whether wallet transactions are in mempool
This avoid calling out to mempool state during coin selection,
balance calculation, etc. In the next commit we ensure all wallet
callbacks from CValidationInterface happen in the same queue,
serialized with each other. This helps to avoid re-introducing one
of the issues described in #9584 [1] by further disconnecting
wallet from current chain/mempool state.
Thanks to @morcos for the suggestion to do this.
Note that there are several race conditions introduced here:
* If a user calls sendrawtransaction from RPC, adding a
transaction which is "trusted" (ie from them) and pays them
change, it may not be immediately used by coin selection until
the notification callbacks finish running. No such race is
introduced in normal transaction-sending RPCs as this case is
explicitly handled.
* Until Block{Connected,Disconnected} and
TransactionAddedToMempool calls also run in the CSceduler
background thread, there is a race where
TransactionAddedToMempool might be called after a
Block{Connected,Disconnected} call happens.
* Wallet will write a new best chain from the SetBestChain
callback prior to having processed the transaction from that
block.
[1] "you could go to select coins, need to use 0-conf change, but
such 0-conf change may have been included in a block who's
callbacks have not yet been processed - resulting in thinking they
are not in mempool and, thus, not selectable."
2017-01-20 18:38:07 -03:00
mutable bool fInMempool ;
2014-12-18 22:03:51 -03:00
mutable CAmount nChangeCached ;
Add wallet privkey encryption.
This commit adds support for ckeys, or enCrypted private keys, to the wallet.
All keys are stored in memory in their encrypted form and thus the passphrase
is required from the user to spend coins, or to create new addresses.
Keys are encrypted with AES-256-CBC using OpenSSL's EVP library. The key is
calculated via EVP_BytesToKey using SHA512 with (by default) 25000 rounds and
a random salt.
By default, the user's wallet remains unencrypted until they call the RPC
command encryptwallet <passphrase> or, from the GUI menu, Options->
Encrypt Wallet.
When the user is attempting to call RPC functions which require the password
to unlock the wallet, an error will be returned unless they call
walletpassphrase <passphrase> <time to keep key in memory> first.
A keypoolrefill command has been added which tops up the users keypool
(requiring the passphrase via walletpassphrase first).
keypoolsize has been added to the output of getinfo to show the user the
number of keys left before they need to specify their passphrase (and call
keypoolrefill).
Note that walletpassphrase will automatically fill keypool in a separate
thread which it spawns when the passphrase is set. This could cause some
delays in other threads waiting for locks on the wallet passphrase, including
one which could cause the passphrase to be stored longer than expected,
however it will not allow the passphrase to be used longer than expected as
ThreadCleanWalletPassphrase will attempt to get a lock on the key as soon
as the specified lock time has arrived.
When the keypool runs out (and wallet is locked) GetOrReuseKeyFromPool
returns vchDefaultKey, meaning miners may start to generate many blocks to
vchDefaultKey instead of a new key each time.
A walletpassphrasechange <oldpassphrase> <newpassphrase> has been added to
allow the user to change their password via RPC.
Whenever keying material (unencrypted private keys, the user's passphrase,
the wallet's AES key) is stored unencrypted in memory, any reasonable attempt
is made to mlock/VirtualLock that memory before storing the keying material.
This is not true in several (commented) cases where mlock/VirtualLocking the
memory is not possible.
Although encryption of private keys in memory can be very useful on desktop
systems (as some small amount of protection against stupid viruses), on an
RPC server, the password is entered fairly insecurely. Thus, the only main
advantage encryption has for RPC servers is for RPC servers that do not spend
coins, except in rare cases, eg. a webserver of a merchant which only receives
payment except for cases of manual intervention.
Thanks to jgarzik for the original patch and sipa, gmaxwell and many others
for all their input.
Conflicts:
src/wallet.cpp
2011-07-08 09:47:35 -04:00
2017-11-20 14:49:26 -03:00
CWalletTx ( const CWallet * wallet , CTransactionRef arg )
: pwallet ( wallet ) ,
tx ( std : : move ( arg ) )
2014-09-28 11:11:17 -03:00
{
2017-11-20 14:49:26 -03:00
Init ( ) ;
2014-09-28 11:11:17 -03:00
}
2017-11-20 14:49:26 -03:00
void Init ( )
2014-06-03 12:55:33 -04:00
{
2014-12-18 22:03:51 -03:00
mapValue . clear ( ) ;
vOrderForm . clear ( ) ;
fTimeReceivedIsTxTime = false ;
nTimeReceived = 0 ;
nTimeSmart = 0 ;
fFromMe = false ;
fChangeCached = false ;
Use callbacks to cache whether wallet transactions are in mempool
This avoid calling out to mempool state during coin selection,
balance calculation, etc. In the next commit we ensure all wallet
callbacks from CValidationInterface happen in the same queue,
serialized with each other. This helps to avoid re-introducing one
of the issues described in #9584 [1] by further disconnecting
wallet from current chain/mempool state.
Thanks to @morcos for the suggestion to do this.
Note that there are several race conditions introduced here:
* If a user calls sendrawtransaction from RPC, adding a
transaction which is "trusted" (ie from them) and pays them
change, it may not be immediately used by coin selection until
the notification callbacks finish running. No such race is
introduced in normal transaction-sending RPCs as this case is
explicitly handled.
* Until Block{Connected,Disconnected} and
TransactionAddedToMempool calls also run in the CSceduler
background thread, there is a race where
TransactionAddedToMempool might be called after a
Block{Connected,Disconnected} call happens.
* Wallet will write a new best chain from the SetBestChain
callback prior to having processed the transaction from that
block.
[1] "you could go to select coins, need to use 0-conf change, but
such 0-conf change may have been included in a block who's
callbacks have not yet been processed - resulting in thinking they
are not in mempool and, thus, not selectable."
2017-01-20 18:38:07 -03:00
fInMempool = false ;
2014-12-18 22:03:51 -03:00
nChangeCached = 0 ;
nOrderPos = - 1 ;
2019-08-12 18:12:12 -04:00
m_confirm = Confirmation { } ;
2011-06-26 13:23:24 -04:00
}
2019-07-25 10:43:54 -04:00
CTransactionRef tx ;
2019-08-12 18:12:12 -04:00
/* New transactions start as UNCONFIRMED. At BlockConnected,
* they will transition to CONFIRMED . In case of reorg , at BlockDisconnected ,
* they roll back to UNCONFIRMED . If we detect a conflicting transaction at
* block connection , we update conflicted tx and its dependencies as CONFLICTED .
* If tx isn ' t confirmed and outside of mempool , the user may switch it to ABANDONED
* by using the abandontransaction call . This last status may be override by a CONFLICTED
* or CONFIRMED transition .
2019-07-25 10:43:54 -04:00
*/
2019-08-12 18:12:12 -04:00
enum Status {
UNCONFIRMED ,
CONFIRMED ,
CONFLICTED ,
ABANDONED
} ;
2019-04-20 11:22:59 -04:00
/* Confirmation includes tx status and a triplet of {block height/block hash/tx index in block}
* at which tx has been confirmed . All three are set to 0 if tx is unconfirmed or abandoned .
* Meaning of these fields changes with CONFLICTED state where they instead point to block hash
* and block height of the deepest conflicting tx .
2019-08-12 18:12:12 -04:00
*/
struct Confirmation {
2019-10-24 13:53:57 -03:00
Status status ;
2019-04-20 11:22:59 -04:00
int block_height ;
2019-10-24 13:53:57 -03:00
uint256 hashBlock ;
int nIndex ;
2019-04-20 11:22:59 -04:00
Confirmation ( Status s = UNCONFIRMED , int b = 0 , uint256 h = uint256 ( ) , int i = 0 ) : status ( s ) , block_height ( b ) , hashBlock ( h ) , nIndex ( i ) { }
2019-08-12 18:12:12 -04:00
} ;
Confirmation m_confirm ;
2019-07-25 10:43:54 -04:00
2018-03-09 22:04:31 -03:00
template < typename Stream >
void Serialize ( Stream & s ) const
{
mapValue_t mapValueCopy = mapValue ;
2011-06-26 13:23:24 -04:00
2018-07-31 12:23:26 -04:00
mapValueCopy [ " fromaccount " ] = " " ;
2018-03-09 22:04:31 -03:00
WriteOrderPos ( nOrderPos , mapValueCopy ) ;
if ( nTimeSmart ) {
mapValueCopy [ " timesmart " ] = strprintf ( " %u " , nTimeSmart ) ;
2014-12-18 22:03:51 -03:00
}
2012-09-27 14:52:09 -03:00
2019-07-24 14:09:28 -04:00
std : : vector < char > dummy_vector1 ; //!< Used to be vMerkleBranch
std : : vector < char > dummy_vector2 ; //!< Used to be vtxPrev
2019-08-08 19:18:30 -04:00
bool dummy_bool = false ; //!< Used to be fSpent
2019-08-12 18:12:12 -04:00
uint256 serializedHash = isAbandoned ( ) ? ABANDON_HASH : m_confirm . hashBlock ;
int serializedIndex = isAbandoned ( ) | | isConflicted ( ) ? - 1 : m_confirm . nIndex ;
s < < tx < < serializedHash < < dummy_vector1 < < serializedIndex < < dummy_vector2 < < mapValueCopy < < vOrderForm < < fTimeReceivedIsTxTime < < nTimeReceived < < fFromMe < < dummy_bool ;
2018-03-09 22:04:31 -03:00
}
2013-06-10 09:36:29 -04:00
2018-03-09 22:04:31 -03:00
template < typename Stream >
void Unserialize ( Stream & s )
{
2017-11-20 14:49:26 -03:00
Init ( ) ;
2014-02-15 18:38:28 -03:00
2019-07-24 14:09:28 -04:00
std : : vector < uint256 > dummy_vector1 ; //!< Used to be vMerkleBranch
std : : vector < CMerkleTx > dummy_vector2 ; //!< Used to be vtxPrev
2019-08-08 19:18:30 -04:00
bool dummy_bool ; //! Used to be fSpent
2019-08-12 18:12:12 -04:00
int serializedIndex ;
s > > tx > > m_confirm . hashBlock > > dummy_vector1 > > serializedIndex > > dummy_vector2 > > mapValue > > vOrderForm > > fTimeReceivedIsTxTime > > nTimeReceived > > fFromMe > > dummy_bool ;
/* At serialization/deserialization, an nIndex == -1 means that hashBlock refers to
* the earliest block in the chain we know this or any in - wallet ancestor conflicts
* with . If nIndex = = - 1 and hashBlock is ABANDON_HASH , it means transaction is abandoned .
* In same context , an nIndex > = 0 refers to a confirmed transaction ( if hashBlock set ) or
* unconfirmed one . Older clients interpret nIndex = = - 1 as unconfirmed for backward
* compatibility ( pre - commit 9 ac63d6 ) .
*/
if ( serializedIndex = = - 1 & & m_confirm . hashBlock = = ABANDON_HASH ) {
setAbandoned ( ) ;
} else if ( serializedIndex = = - 1 ) {
setConflicted ( ) ;
} else if ( ! m_confirm . hashBlock . IsNull ( ) ) {
m_confirm . nIndex = serializedIndex ;
setConfirmed ( ) ;
}
2012-03-21 23:56:31 -03:00
2018-03-09 22:04:31 -03:00
ReadOrderPos ( nOrderPos , mapValue ) ;
nTimeSmart = mapValue . count ( " timesmart " ) ? ( unsigned int ) atoi64 ( mapValue [ " timesmart " ] ) : 0 ;
2013-12-12 04:07:59 -03:00
2014-12-18 22:03:51 -03:00
mapValue . erase ( " fromaccount " ) ;
mapValue . erase ( " spent " ) ;
mapValue . erase ( " n " ) ;
mapValue . erase ( " timesmart " ) ;
}
2014-02-15 18:38:28 -03:00
2019-07-25 10:43:54 -04:00
void SetTx ( CTransactionRef arg )
{
tx = std : : move ( arg ) ;
}
2014-12-18 22:03:51 -03:00
//! make sure balances are recalculated
void MarkDirty ( )
{
2019-04-09 22:40:35 -04:00
m_amounts [ DEBIT ] . Reset ( ) ;
m_amounts [ CREDIT ] . Reset ( ) ;
m_amounts [ IMMATURE_CREDIT ] . Reset ( ) ;
m_amounts [ AVAILABLE_CREDIT ] . Reset ( ) ;
2014-12-18 22:03:51 -03:00
fChangeCached = false ;
2020-01-07 10:47:20 -03:00
m_is_cache_empty = true ;
2014-12-18 22:03:51 -03:00
}
//! filter decides which addresses will count towards the debit
CAmount GetDebit ( const isminefilter & filter ) const ;
2019-04-29 09:52:01 -04:00
CAmount GetCredit ( const isminefilter & filter ) const ;
CAmount GetImmatureCredit ( bool fUseCache = true ) const ;
2018-08-26 16:48:03 -03:00
// TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
2019-03-06 18:47:57 -03:00
// annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The
2018-08-26 16:48:03 -03:00
// annotation "NO_THREAD_SAFETY_ANALYSIS" was temporarily added to avoid
// having to resolve the issue of member access into incomplete type CWallet.
2019-04-29 09:52:01 -04:00
CAmount GetAvailableCredit ( bool fUseCache = true , const isminefilter & filter = ISMINE_SPENDABLE ) const NO_THREAD_SAFETY_ANALYSIS ;
CAmount GetImmatureWatchOnlyCredit ( const bool fUseCache = true ) const ;
2014-12-18 22:03:51 -03:00
CAmount GetChange ( ) const ;
2018-03-05 18:37:24 -03:00
// Get the marginal bytes if spending the specified output from this transaction
2018-08-07 19:59:53 -04:00
int GetSpendSize ( unsigned int out , bool use_max_sig = false ) const
2018-03-05 18:37:24 -03:00
{
2018-08-07 19:59:53 -04:00
return CalculateMaximumSignedInputSize ( tx - > vout [ out ] , pwallet , use_max_sig ) ;
2018-03-05 18:37:24 -03:00
}
2014-12-18 22:03:51 -03:00
void GetAmounts ( std : : list < COutputEntry > & listReceived ,
2018-07-31 12:23:26 -04:00
std : : list < COutputEntry > & listSent , CAmount & nFee , const isminefilter & filter ) const ;
2014-12-18 22:03:51 -03:00
bool IsFromMe ( const isminefilter & filter ) const
{
return ( GetDebit ( filter ) > 0 ) ;
}
2015-07-02 15:57:39 -03:00
// True if only scriptSigs are different
bool IsEquivalentTo ( const CWalletTx & tx ) const ;
2015-11-30 12:15:15 -03:00
bool InMempool ( ) const ;
2019-07-16 17:01:46 -04:00
bool IsTrusted ( ) const ;
2014-12-18 22:03:51 -03:00
int64_t GetTxTime ( ) const ;
2019-04-11 11:58:53 -04:00
// Pass this transaction to node for mempool insertion and relay to peers if flag set to true
2019-04-29 09:52:01 -04:00
bool SubmitMemoryPoolAndRelay ( std : : string & err_string , bool relay ) ;
Use callbacks to cache whether wallet transactions are in mempool
This avoid calling out to mempool state during coin selection,
balance calculation, etc. In the next commit we ensure all wallet
callbacks from CValidationInterface happen in the same queue,
serialized with each other. This helps to avoid re-introducing one
of the issues described in #9584 [1] by further disconnecting
wallet from current chain/mempool state.
Thanks to @morcos for the suggestion to do this.
Note that there are several race conditions introduced here:
* If a user calls sendrawtransaction from RPC, adding a
transaction which is "trusted" (ie from them) and pays them
change, it may not be immediately used by coin selection until
the notification callbacks finish running. No such race is
introduced in normal transaction-sending RPCs as this case is
explicitly handled.
* Until Block{Connected,Disconnected} and
TransactionAddedToMempool calls also run in the CSceduler
background thread, there is a race where
TransactionAddedToMempool might be called after a
Block{Connected,Disconnected} call happens.
* Wallet will write a new best chain from the SetBestChain
callback prior to having processed the transaction from that
block.
[1] "you could go to select coins, need to use 0-conf change, but
such 0-conf change may have been included in a block who's
callbacks have not yet been processed - resulting in thinking they
are not in mempool and, thus, not selectable."
2017-01-20 18:38:07 -03:00
2018-08-26 16:48:03 -03:00
// TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
// annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The annotation
// "NO_THREAD_SAFETY_ANALYSIS" was temporarily added to avoid having to
// resolve the issue of member access into incomplete type CWallet. Note
// that we still have the runtime check "AssertLockHeld(pwallet->cs_wallet)"
// in place.
std : : set < uint256 > GetConflicts ( ) const NO_THREAD_SAFETY_ANALYSIS ;
2019-07-25 10:42:34 -04:00
/**
* Return depth of transaction in blockchain :
* < 0 : conflicts with a transaction this deep in the blockchain
* 0 : in memory pool , waiting to be included in a block
* > = 1 : this many blocks deep in the main chain
*/
2019-04-22 14:22:25 -04:00
// TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
// annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The annotation
// "NO_THREAD_SAFETY_ANALYSIS" was temporarily added to avoid having to
// resolve the issue of member access into incomplete type CWallet. Note
// that we still have the runtime check "AssertLockHeld(pwallet->cs_wallet)"
// in place.
2019-04-29 09:52:01 -04:00
int GetDepthInMainChain ( ) const NO_THREAD_SAFETY_ANALYSIS ;
bool IsInMainChain ( ) const { return GetDepthInMainChain ( ) > 0 ; }
2019-07-25 10:42:34 -04:00
/**
* @ return number of blocks to maturity for this transaction :
* 0 : is not a coinbase transaction , or is a mature coinbase transaction
* > 0 : is a coinbase transaction which matures in this many blocks
*/
2019-04-29 09:52:01 -04:00
int GetBlocksToMaturity ( ) const ;
2019-08-12 18:12:12 -04:00
bool isAbandoned ( ) const { return m_confirm . status = = CWalletTx : : ABANDONED ; }
void setAbandoned ( )
{
m_confirm . status = CWalletTx : : ABANDONED ;
m_confirm . hashBlock = uint256 ( ) ;
2019-04-20 11:22:59 -04:00
m_confirm . block_height = 0 ;
2019-08-12 18:12:12 -04:00
m_confirm . nIndex = 0 ;
}
bool isConflicted ( ) const { return m_confirm . status = = CWalletTx : : CONFLICTED ; }
void setConflicted ( ) { m_confirm . status = CWalletTx : : CONFLICTED ; }
bool isUnconfirmed ( ) const { return m_confirm . status = = CWalletTx : : UNCONFIRMED ; }
void setUnconfirmed ( ) { m_confirm . status = CWalletTx : : UNCONFIRMED ; }
2019-04-20 11:22:59 -04:00
bool isConfirmed ( ) const { return m_confirm . status = = CWalletTx : : CONFIRMED ; }
2019-08-12 18:12:12 -04:00
void setConfirmed ( ) { m_confirm . status = CWalletTx : : CONFIRMED ; }
2019-07-25 10:42:34 -04:00
const uint256 & GetHash ( ) const { return tx - > GetHash ( ) ; }
bool IsCoinBase ( ) const { return tx - > IsCoinBase ( ) ; }
2019-04-29 09:52:01 -04:00
bool IsImmatureCoinBase ( ) const ;
2017-11-20 14:51:45 -03:00
// Disable copying of CWalletTx objects to prevent bugs where instances get
// copied in and out of the mapWallet map, and fields are updated in the
// wrong copy.
CWalletTx ( CWalletTx const & ) = delete ;
void operator = ( CWalletTx const & x ) = delete ;
2014-12-18 22:03:51 -03:00
} ;
class COutput
{
public :
const CWalletTx * tx ;
int i ;
int nDepth ;
2017-02-23 13:20:16 -03:00
2018-03-05 18:37:24 -03:00
/** 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 ;
2017-02-23 13:20:16 -03:00
/** Whether we have the private keys to spend this output */
2014-12-18 22:03:51 -03:00
bool fSpendable ;
2017-02-23 13:20:16 -03:00
/** Whether we know how to spend this output, ignoring the lack of keys */
2016-03-14 15:22:11 -03:00
bool fSolvable ;
2014-12-18 22:03:51 -03:00
2018-08-07 19:59:53 -04:00
/** 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 ;
2017-02-23 13:20:16 -03:00
/**
* 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 ;
2018-08-07 19:59:53 -04:00
COutput ( const CWalletTx * txIn , int iIn , int nDepthIn , bool fSpendableIn , bool fSolvableIn , bool fSafeIn , bool use_max_sig_in = false )
2014-12-18 22:03:51 -03:00
{
2018-08-07 19:59:53 -04:00
tx = txIn ; i = iIn ; nDepth = nDepthIn ; fSpendable = fSpendableIn ; fSolvable = fSolvableIn ; fSafe = fSafeIn ; nInputBytes = - 1 ; use_max_sig = use_max_sig_in ;
2018-03-05 18:37:24 -03:00
// If known and signable by the given wallet, compute nInputBytes
// Failure will keep this value -1
if ( fSpendable & & tx ) {
2018-08-07 19:59:53 -04:00
nInputBytes = tx - > GetSpendSize ( i , use_max_sig ) ;
2018-03-05 18:37:24 -03:00
}
2014-12-18 22:03:51 -03:00
}
std : : string ToString ( ) const ;
2018-07-17 03:56:06 -04:00
inline CInputCoin GetInputCoin ( ) const
{
return CInputCoin ( tx - > tx , i , nInputBytes ) ;
}
2014-12-18 22:03:51 -03:00
} ;
2018-03-05 18:42:49 -03:00
struct CoinSelectionParams
{
bool use_bnb = true ;
size_t change_output_size = 0 ;
size_t change_spend_size = 0 ;
CFeeRate effective_fee = CFeeRate ( 0 ) ;
size_t tx_noinputs_size = 0 ;
2019-10-25 19:45:58 -03:00
//! Indicate that we are subtracting the fee from outputs
bool m_subtract_fee_outputs = false ;
2018-03-05 18:42:49 -03:00
CoinSelectionParams ( bool use_bnb , size_t change_output_size , size_t change_spend_size , CFeeRate effective_fee , size_t tx_noinputs_size ) : use_bnb ( use_bnb ) , change_output_size ( change_output_size ) , change_spend_size ( change_spend_size ) , effective_fee ( effective_fee ) , tx_noinputs_size ( tx_noinputs_size ) { }
CoinSelectionParams ( ) { }
} ;
2017-12-12 20:13:58 -03:00
class WalletRescanReserver ; //forward declarations for ScanForWalletTransactions/RescanFromTime
2018-04-17 14:22:23 -03:00
/**
2019-10-07 15:11:34 -03:00
* A CWallet maintains a set of transactions and balances , and provides the ability to create new transactions .
2014-12-18 22:03:51 -03:00
*/
2020-03-10 16:46:20 -03:00
class CWallet final : public WalletStorage , public interfaces : : Chain : : Notifications
2014-12-18 22:03:51 -03:00
{
private :
2019-10-07 15:11:34 -03:00
CKeyingMaterial vMasterKey GUARDED_BY ( cs_wallet ) ;
2019-06-06 17:58:21 -04:00
bool Unlock ( const CKeyingMaterial & vMasterKeyIn , bool accept_no_keys = false ) ;
2018-03-26 05:52:32 -03:00
std : : atomic < bool > fAbortRescan { false } ;
std : : atomic < bool > fScanningWallet { false } ; // controlled by WalletRescanReserver
2019-04-03 12:57:24 -03:00
std : : atomic < int64_t > m_scanning_start { 0 } ;
2019-04-03 13:05:52 -03:00
std : : atomic < double > m_scanning_progress { 0 } ;
2017-12-08 18:07:37 -03:00
friend class WalletRescanReserver ;
2014-12-18 22:03:51 -03:00
//! the current wallet version: clients below this version are not able to load the wallet
2019-02-18 18:09:45 -03:00
int nWalletVersion GUARDED_BY ( cs_wallet ) { FEATURE_BASE } ;
2014-12-18 22:03:51 -03:00
//! the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded
2018-10-09 07:03:01 -03:00
int nWalletMaxVersion GUARDED_BY ( cs_wallet ) = FEATURE_BASE ;
2014-12-18 22:03:51 -03:00
2018-03-26 05:52:32 -03:00
int64_t nNextResend = 0 ;
bool fBroadcastTransactions = false ;
2019-03-28 14:15:47 -03:00
// Local time that the tip block was received. Used to schedule wallet rebroadcasts.
std : : atomic < int64_t > m_best_block_time { 0 } ;
2014-12-18 22:03:51 -03:00
/**
* Used to keep track of spent outpoints , and
* detect and report conflicts ( double - spends or
* mutated transactions where the mutant gets mined ) .
*/
typedef std : : multimap < COutPoint , uint256 > TxSpends ;
2018-08-26 16:48:03 -03:00
TxSpends mapTxSpends GUARDED_BY ( cs_wallet ) ;
void AddToSpends ( const COutPoint & outpoint , const uint256 & wtxid ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
void AddToSpends ( const uint256 & wtxid ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2014-12-18 22:03:51 -03:00
2018-07-12 16:07:19 -04:00
/**
* Add a transaction to the wallet , or update it . pIndex and posInBlock should
* be set when the transaction was known to be included in a block . When
* pIndex = = nullptr , then wallet state is not updated in AddToWallet , but
* notifications happen and cached balances are marked dirty .
*
* If fUpdate is true , existing transactions will be updated .
* TODO : One exception to this is that the abandoned state is cleared under the
* assumption that any further notification of a transaction that was considered
* abandoned is an indication that it is not safe to be considered abandoned .
* Abandoned state should probably be more carefully tracked via different
* posInBlock signals or by checking mempool presence when necessary .
*/
2019-10-24 13:53:57 -03:00
bool AddToWalletIfInvolvingMe ( const CTransactionRef & tx , CWalletTx : : Confirmation confirm , bool fUpdate ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2018-07-12 16:07:19 -04:00
2015-11-26 14:42:07 -03:00
/* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */
2019-04-20 11:22:59 -04:00
void MarkConflicted ( const uint256 & hashBlock , int conflicting_height , const uint256 & hashTx ) ;
2015-11-26 14:42:07 -03:00
2018-07-12 16:02:31 -04:00
/* Mark a transaction's inputs dirty, thus forcing the outputs to be recomputed */
2018-08-26 16:48:03 -03:00
void MarkInputsDirty ( const CTransactionRef & tx ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2018-07-12 16:02:31 -04:00
2018-08-26 16:48:03 -03:00
void SyncMetaData ( std : : pair < TxSpends : : iterator , TxSpends : : iterator > ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2014-12-18 22:03:51 -03:00
2018-04-10 23:12:48 -03:00
/* Used by TransactionAddedToMemorypool/BlockConnected/Disconnected/ScanForWalletTransactions.
2019-01-08 04:38:53 -03:00
* Should be called with non - zero block_hash and posInBlock if this is for a transaction that is included in a block . */
2019-10-24 13:53:57 -03:00
void SyncTransaction ( const CTransactionRef & tx , CWalletTx : : Confirmation confirm , bool update_tx = true ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2017-03-29 22:12:42 -03:00
2017-02-16 10:22:18 -03:00
std : : atomic < uint64_t > m_wallet_flags { 0 } ;
2016-11-08 18:28:20 -03:00
2019-04-04 06:33:02 -03:00
bool SetAddressBookWithDB ( WalletBatch & batch , const CTxDestination & address , const std : : string & strName , const std : : string & strPurpose ) ;
2019-05-18 06:01:56 -04:00
//! Unsets a wallet flag and saves it to disk
2019-10-29 18:53:35 -03:00
void UnsetWalletFlagWithDB ( WalletBatch & batch , uint64_t flag ) ;
//! Unset the blank wallet flag and saves it to disk
void UnsetBlankWalletFlag ( WalletBatch & batch ) override ;
2016-11-08 18:55:02 -03:00
2017-05-30 15:55:17 -04:00
/** Interface for accessing chain state. */
2019-03-22 01:24:55 -03:00
interfaces : : Chain * m_chain ;
2017-05-30 15:55:17 -04:00
2020-07-28 19:25:14 -04:00
/** Wallet name: relative directory name or "" for default wallet. */
std : : string m_name ;
2017-11-13 23:25:46 -03:00
/** Internal database handle. */
2017-12-08 08:39:22 -03:00
std : : unique_ptr < WalletDatabase > database ;
2017-03-08 07:48:58 -03:00
2017-01-17 20:06:16 -03:00
/**
* The following is used to keep track of how far behind the wallet is
* from the chain sync , and to allow clients to block on us being caught up .
*
2019-04-20 12:02:52 -04:00
* Processed hash is a pointer on node ' s tip and doesn ' t imply that the wallet
* has scanned sequentially all blocks up to this one .
2017-01-17 20:06:16 -03:00
*/
2019-04-18 08:21:35 -04:00
uint256 m_last_block_processed GUARDED_BY ( cs_wallet ) ;
2017-01-17 20:06:16 -03:00
2019-04-20 12:02:52 -04:00
/* Height of last block processed is used by wallet to know depth of transactions
* without relying on Chain interface beyond asynchronous updates . For safety , we
* initialize it to - 1. Height is a pointer on node ' s tip and doesn ' t imply
* that the wallet has scanned sequentially all blocks up to this one .
*/
int m_last_block_processed_height GUARDED_BY ( cs_wallet ) = - 1 ;
2019-10-07 15:11:34 -03:00
std : : map < OutputType , ScriptPubKeyMan * > m_external_spk_managers ;
std : : map < OutputType , ScriptPubKeyMan * > m_internal_spk_managers ;
// Indexed by a unique identifier produced by each ScriptPubKeyMan using
// ScriptPubKeyMan::GetID. In many cases it will be the hash of an internal structure
std : : map < uint256 , std : : unique_ptr < ScriptPubKeyMan > > m_spk_managers ;
2020-07-12 15:52:02 -04:00
bool CreateTransactionInternal ( const std : : vector < CRecipient > & vecSend , CTransactionRef & tx , CAmount & nFeeRet , int & nChangePosInOut , bilingual_str & error , const CCoinControl & coin_control , FeeCalculation & fee_calc_out , bool sign ) ;
2018-10-25 21:36:56 -03:00
2014-12-18 22:03:51 -03:00
public :
/*
* Main wallet lock .
2017-03-08 09:08:26 -03:00
* This lock protects all the fields added by CWallet .
2014-12-18 22:03:51 -03:00
*/
2020-01-07 13:14:15 -03:00
mutable RecursiveMutex cs_wallet ;
2014-12-18 22:03:51 -03:00
2017-03-08 07:48:58 -03:00
/** Get database handle used by this wallet. Ideally this function would
* not be necessary .
*/
2017-12-08 08:39:22 -03:00
WalletDatabase & GetDBHandle ( )
2017-03-08 07:48:58 -03:00
{
2017-12-08 08:39:22 -03:00
return * database ;
2017-03-08 07:48:58 -03:00
}
2019-10-07 15:11:34 -03:00
WalletDatabase & GetDatabase ( ) override { return * database ; }
2017-03-08 07:48:58 -03:00
2018-03-15 12:25:50 -03:00
/**
* Select a set of coins such that nValueRet > = nTargetValue and at least
* all coins from coinControl are selected ; Never select unconfirmed coins
* if they are not ours
*/
bool SelectCoins ( const std : : vector < COutput > & vAvailableCoins , const CAmount & nTargetValue , std : : set < CInputCoin > & setCoinsRet , CAmount & nValueRet ,
2018-08-26 16:48:03 -03:00
const CCoinControl & coin_control , CoinSelectionParams & coin_selection_params , bool & bnb_used ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2018-03-15 12:25:50 -03:00
2017-03-08 07:48:58 -03:00
/** Get a name for this wallet for logging/debugging purposes.
*/
2020-07-28 19:25:14 -04:00
const std : : string & GetName ( ) const { return m_name ; }
2014-12-18 22:03:51 -03:00
typedef std : : map < unsigned int , CMasterKey > MasterKeyMap ;
MasterKeyMap mapMasterKeys ;
2018-03-26 05:52:32 -03:00
unsigned int nMasterKeyMaxID = 0 ;
2014-12-18 22:03:51 -03:00
2017-11-13 23:25:46 -03:00
/** Construct wallet with specified name and database implementation. */
2020-07-28 19:25:14 -04:00
CWallet ( interfaces : : Chain * chain , const std : : string & name , std : : unique_ptr < WalletDatabase > database )
2019-12-05 20:14:53 -03:00
: m_chain ( chain ) ,
2020-07-28 19:25:14 -04:00
m_name ( name ) ,
2019-04-17 13:27:02 -04:00
database ( std : : move ( database ) )
2014-12-18 22:03:51 -03:00
{
}
~ CWallet ( )
{
2018-12-12 20:21:19 -03:00
// Should not have slots connected at this point.
assert ( NotifyUnload . empty ( ) ) ;
2014-12-18 22:03:51 -03:00
}
2019-12-05 20:14:53 -03:00
bool IsCrypted ( ) const ;
2019-10-07 15:11:34 -03:00
bool IsLocked ( ) const override ;
2019-06-06 17:58:21 -04:00
bool Lock ( ) ;
2019-07-15 18:20:12 -04:00
/** Interface to assert chain access */
bool HaveChain ( ) const { return m_chain ? true : false ; }
2018-08-26 16:48:03 -03:00
std : : map < uint256 , CWalletTx > mapWallet GUARDED_BY ( cs_wallet ) ;
2015-10-19 06:19:38 -03:00
2018-07-31 12:23:26 -04:00
typedef std : : multimap < int64_t , CWalletTx * > TxItems ;
2015-10-19 06:19:38 -03:00
TxItems wtxOrdered ;
2014-12-18 22:03:51 -03:00
2018-10-09 07:03:01 -03:00
int64_t nOrderPosNext GUARDED_BY ( cs_wallet ) = 0 ;
2018-03-26 05:52:32 -03:00
uint64_t nAccountingEntryNumber = 0 ;
2014-12-18 22:03:51 -03:00
2020-02-21 18:52:52 -03:00
std : : map < CTxDestination , CAddressBookData > m_address_book GUARDED_BY ( cs_wallet ) ;
2020-02-21 23:50:46 -03:00
const CAddressBookData * FindAddressBookEntry ( const CTxDestination & , bool allow_change = false ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2014-12-18 22:03:51 -03:00
2018-10-09 08:57:46 -03:00
std : : set < COutPoint > setLockedCoins GUARDED_BY ( cs_wallet ) ;
2014-12-18 22:03:51 -03:00
2017-07-30 16:00:56 -04:00
/** Registered interfaces::Chain::Notifications handler. */
std : : unique_ptr < interfaces : : Handler > m_chain_notifications_handler ;
2017-05-30 15:55:17 -04:00
/** Interface for accessing chain state. */
2019-03-22 01:24:55 -03:00
interfaces : : Chain & chain ( ) const { assert ( m_chain ) ; return * m_chain ; }
2017-05-30 15:55:17 -04:00
2020-06-15 17:57:57 -04:00
const CWalletTx * GetWalletTx ( const uint256 & hash ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2020-08-20 20:06:53 -04:00
bool IsTrusted ( const CWalletTx & wtx , std : : set < uint256 > & trusted_parents ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2014-12-18 22:03:51 -03:00
//! check whether we are allowed to upgrade (or already support) to the named feature
2019-10-07 15:11:34 -03:00
bool CanSupportFeature ( enum WalletFeature wf ) const override EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) { AssertLockHeld ( cs_wallet ) ; return nWalletMaxVersion > = wf ; }
2014-12-18 22:03:51 -03:00
2015-09-13 18:23:59 -03:00
/**
* populate vCoins with vector of available COutputs .
*/
2019-07-16 17:01:46 -04:00
void AvailableCoins ( std : : vector < COutput > & vCoins , bool fOnlySafe = true , const CCoinControl * coinControl = nullptr , const CAmount & nMinimumAmount = 1 , const CAmount & nMaximumAmount = MAX_MONEY , const CAmount & nMinimumSumAmount = MAX_MONEY , const uint64_t nMaximumCount = 0 ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2015-09-14 09:49:59 -03:00
2017-04-28 15:10:21 -03:00
/**
* Return list of available coins and locked coins grouped by non - change output address .
*/
2019-07-16 17:01:46 -04:00
std : : map < CTxDestination , std : : vector < COutput > > ListCoins ( ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2017-04-28 15:10:21 -03:00
/**
* Find non - change parent output .
*/
2018-08-26 16:48:03 -03:00
const CTxOut & FindNonChangeParentOutput ( const CTransaction & tx , int output ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2017-04-28 15:10:21 -03:00
2015-09-13 18:23:59 -03:00
/**
2015-09-14 09:49:59 -03:00
* Shuffle and select coins until nTargetValue is reached while avoiding
* small change ; This method is stochastic for some inputs and upon
* completion the coin set and corresponding actual target value is
* assembled
2015-09-13 18:23:59 -03:00
*/
2018-07-18 22:45:26 -04:00
bool SelectCoinsMinConf ( const CAmount & nTargetValue , const CoinEligibilityFilter & eligibility_filter , std : : vector < OutputGroup > groups ,
2018-03-05 18:42:49 -03:00
std : : set < CInputCoin > & setCoinsRet , CAmount & nValueRet , const CoinSelectionParams & coin_selection_params , bool & bnb_used ) const ;
2014-12-18 22:03:51 -03:00
2019-04-29 09:52:01 -04:00
bool IsSpent ( const uint256 & hash , unsigned int n ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2018-09-13 01:53:19 -03:00
2019-11-27 12:56:04 -03:00
// Whether this or any known UTXO with the same single key has been spent.
2020-02-21 18:15:13 -03:00
bool IsSpentKey ( const uint256 & hash , unsigned int n ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
void SetSpentKeyState ( WalletBatch & batch , const uint256 & hash , unsigned int n , bool used , std : : set < CTxDestination > & tx_destinations ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2018-09-13 01:53:19 -03:00
2019-12-28 21:58:46 -03:00
std : : vector < OutputGroup > GroupOutputs ( const std : : vector < COutput > & outputs , bool single_coin , const size_t max_ancestors ) const ;
2014-12-18 22:03:51 -03:00
2018-04-25 18:16:16 -03:00
bool IsLockedCoin ( uint256 hash , unsigned int n ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
void LockCoin ( const COutPoint & output ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
void UnlockCoin ( const COutPoint & output ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
void UnlockAllCoins ( ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
void ListLockedCoins ( std : : vector < COutPoint > & vOutpts ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2012-02-27 09:19:32 -03:00
2017-04-17 11:32:01 -03:00
/*
* Rescan abort properties
*/
void AbortRescan ( ) { fAbortRescan = true ; }
2020-03-02 05:17:33 -03:00
bool IsAbortingRescan ( ) const { return fAbortRescan ; }
bool IsScanning ( ) const { return fScanningWallet ; }
2019-04-03 12:57:24 -03:00
int64_t ScanningDuration ( ) const { return fScanningWallet ? GetTimeMillis ( ) - m_scanning_start : 0 ; }
2019-04-03 13:05:52 -03:00
double ScanningProgress ( ) const { return fScanningWallet ? ( double ) m_scanning_progress : 0 ; }
2017-04-17 11:32:01 -03:00
2018-11-06 11:23:37 -03:00
//! Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo
void UpgradeKeyMetadata ( ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2011-11-06 20:05:42 -03:00
2018-04-25 18:16:16 -03:00
bool LoadMinVersion ( int nVersion ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) { AssertLockHeld ( cs_wallet ) ; nWalletVersion = nVersion ; nWalletMaxVersion = std : : max ( nWalletMaxVersion , nVersion ) ; return true ; }
Add wallet privkey encryption.
This commit adds support for ckeys, or enCrypted private keys, to the wallet.
All keys are stored in memory in their encrypted form and thus the passphrase
is required from the user to spend coins, or to create new addresses.
Keys are encrypted with AES-256-CBC using OpenSSL's EVP library. The key is
calculated via EVP_BytesToKey using SHA512 with (by default) 25000 rounds and
a random salt.
By default, the user's wallet remains unencrypted until they call the RPC
command encryptwallet <passphrase> or, from the GUI menu, Options->
Encrypt Wallet.
When the user is attempting to call RPC functions which require the password
to unlock the wallet, an error will be returned unless they call
walletpassphrase <passphrase> <time to keep key in memory> first.
A keypoolrefill command has been added which tops up the users keypool
(requiring the passphrase via walletpassphrase first).
keypoolsize has been added to the output of getinfo to show the user the
number of keys left before they need to specify their passphrase (and call
keypoolrefill).
Note that walletpassphrase will automatically fill keypool in a separate
thread which it spawns when the passphrase is set. This could cause some
delays in other threads waiting for locks on the wallet passphrase, including
one which could cause the passphrase to be stored longer than expected,
however it will not allow the passphrase to be used longer than expected as
ThreadCleanWalletPassphrase will attempt to get a lock on the key as soon
as the specified lock time has arrived.
When the keypool runs out (and wallet is locked) GetOrReuseKeyFromPool
returns vchDefaultKey, meaning miners may start to generate many blocks to
vchDefaultKey instead of a new key each time.
A walletpassphrasechange <oldpassphrase> <newpassphrase> has been added to
allow the user to change their password via RPC.
Whenever keying material (unencrypted private keys, the user's passphrase,
the wallet's AES key) is stored unencrypted in memory, any reasonable attempt
is made to mlock/VirtualLock that memory before storing the keying material.
This is not true in several (commented) cases where mlock/VirtualLocking the
memory is not possible.
Although encryption of private keys in memory can be very useful on desktop
systems (as some small amount of protection against stupid viruses), on an
RPC server, the password is entered fairly insecurely. Thus, the only main
advantage encryption has for RPC servers is for RPC servers that do not spend
coins, except in rare cases, eg. a webserver of a merchant which only receives
payment except for cases of manual intervention.
Thanks to jgarzik for the original patch and sipa, gmaxwell and many others
for all their input.
Conflicts:
src/wallet.cpp
2011-07-08 09:47:35 -04:00
2020-02-22 02:02:18 -03:00
/**
* Adds a destination data tuple to the store , and saves it to disk
* When adding new fields , take care to consider how DelAddressBook should handle it !
*/
2019-11-02 13:20:45 -03:00
bool AddDestData ( WalletBatch & batch , const CTxDestination & dest , const std : : string & key , const std : : string & value ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2014-10-26 04:03:12 -03:00
//! Erases a destination data tuple in the store and on disk
2019-11-02 13:20:45 -03:00
bool EraseDestData ( WalletBatch & batch , const CTxDestination & dest , const std : : string & key ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2014-10-26 04:03:12 -03:00
//! Adds a destination data tuple to the store, without saving it to disk
2019-02-07 16:46:08 -03:00
void LoadDestData ( const CTxDestination & dest , const std : : string & key , const std : : string & value ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2014-10-26 04:03:12 -03:00
//! Look up a destination data tuple in the store, return true if found false otherwise
2019-02-07 16:46:08 -03:00
bool GetDestData ( const CTxDestination & dest , const std : : string & key , std : : string * value ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2017-04-28 15:10:21 -03:00
//! Get all destination values matching a prefix.
2019-02-07 16:46:08 -03:00
std : : vector < std : : string > GetDestValues ( const std : : string & prefix ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2013-11-18 12:55:54 -03:00
2016-09-09 04:48:10 -03:00
//! Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock().
2020-04-29 05:45:12 -04:00
int64_t nRelockTime GUARDED_BY ( cs_wallet ) { 0 } ;
2016-09-09 04:48:10 -03:00
2020-04-29 05:45:12 -04:00
// Used to prevent concurrent calls to walletpassphrase RPC.
Mutex m_unlock_mutex ;
2016-09-16 11:45:36 -03:00
bool Unlock ( const SecureString & strWalletPassphrase , bool accept_no_keys = false ) ;
2011-11-26 03:02:04 -03:00
bool ChangeWalletPassphrase ( const SecureString & strOldWalletPassphrase , const SecureString & strNewWalletPassphrase ) ;
bool EncryptWallet ( const SecureString & strWalletPassphrase ) ;
2011-06-25 08:57:32 -04:00
2019-12-18 19:46:53 -03:00
void GetKeyBirthTimes ( std : : map < CKeyID , int64_t > & mapKeyBirth ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2016-12-16 12:00:26 -03:00
unsigned int ComputeTimeSmart ( const CWalletTx & wtx ) const ;
2013-04-29 13:50:40 -04:00
2018-04-17 14:22:23 -03:00
/**
2014-10-26 04:03:12 -03:00
* Increment the next transaction order id
* @ return next transaction order id
2012-09-08 01:55:36 -03:00
*/
2018-04-25 18:16:16 -03:00
int64_t IncOrderPosNext ( WalletBatch * batch = nullptr ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2016-09-09 23:21:44 -03:00
DBErrors ReorderTransactions ( ) ;
2012-09-08 01:55:36 -03:00
2011-07-13 05:56:38 -04:00
void MarkDirty ( ) ;
2016-12-19 13:25:15 -03:00
//! Callback for updating transaction metadata in mapWallet.
//!
//! @param wtx - reference to mapWallet transaction to update
//! @param new_tx - true if wtx is newly inserted, false if it previously existed
//!
//! @return true if wtx is changed and needs to be saved to disk, otherwise false
using UpdateWalletTxFn = std : : function < bool ( CWalletTx & wtx , bool new_tx ) > ;
CWalletTx * AddToWallet ( CTransactionRef tx , const CWalletTx : : Confirmation & confirm , const UpdateWalletTxFn & update_wtx = nullptr , bool fFlushOnClose = true ) ;
2019-11-08 11:03:51 -03:00
bool LoadToWallet ( const uint256 & hash , const UpdateWalletTxFn & fill_wtx ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
Add 'sequence' zmq publisher to track all block (dis)connects, mempool deltas
Using the zmq notifications to avoid excessive mempool polling can be difficult
given the current notifications available. It announces all transactions
being added to mempool or included in blocks, but announces no evictions
and gives no indication if the transaction is in the mempool or a block.
Block notifications for zmq are also substandard, in that it only announces
block tips, while all block transactions are still announced.
This commit adds a unified stream which can be used to closely track mempool:
1) getrawmempool to fill out mempool knowledge
2) if txhash is announced, add or remove from set
based on add/remove flag
3) if blockhash is announced, get block txn list,
remove from those transactions local view of mempool
4) if we drop a sequence number, go to (1)
The mempool sequence number starts at the value 1, and
increments each time a transaction enters the mempool,
or is evicted from the mempool for any reason, including
block inclusion. The mempool sequence number is published
via ZMQ for any transaction-related notification.
These features allow for ZMQ/RPC consumer to track mempool
state in a more exacting way, without unnecesarily polling
getrawmempool. See interface_zmq.py::test_mempool_sync for
example usage.
2020-09-04 11:55:58 -04:00
void transactionAddedToMempool ( const CTransactionRef & tx , uint64_t mempool_sequence ) override ;
2020-02-26 18:05:49 -03:00
void blockConnected ( const CBlock & block , int height ) override ;
void blockDisconnected ( const CBlock & block , int height ) override ;
void updatedBlockTip ( ) override ;
2017-12-12 20:13:58 -03:00
int64_t RescanFromTime ( int64_t startTime , const WalletRescanReserver & reserver , bool update ) ;
2018-04-29 12:45:44 -03:00
2019-01-08 04:38:53 -03:00
struct ScanResult {
enum { SUCCESS , FAILURE , USER_ABORT } status = SUCCESS ;
//! Hash and height of most recent block that was successfully scanned.
//! Unset if no blocks were scanned due to read errors or the chain
//! being empty.
2019-01-31 19:42:56 -03:00
uint256 last_scanned_block ;
Optional < int > last_scanned_height ;
2019-01-08 04:38:53 -03:00
//! Height of the most recent block that could not be scanned due to
//! read errors or pruning. Will be set if status is FAILURE, unset if
//! status is SUCCESS, and may or may not be set if status is
//! USER_ABORT.
2019-01-31 19:42:56 -03:00
uint256 last_failed_block ;
2018-04-29 12:45:44 -03:00
} ;
2020-01-22 18:53:42 -03:00
ScanResult ScanForWalletTransactions ( const uint256 & start_block , int start_height , Optional < int > max_height , const WalletRescanReserver & reserver , bool fUpdate ) ;
Add 'sequence' zmq publisher to track all block (dis)connects, mempool deltas
Using the zmq notifications to avoid excessive mempool polling can be difficult
given the current notifications available. It announces all transactions
being added to mempool or included in blocks, but announces no evictions
and gives no indication if the transaction is in the mempool or a block.
Block notifications for zmq are also substandard, in that it only announces
block tips, while all block transactions are still announced.
This commit adds a unified stream which can be used to closely track mempool:
1) getrawmempool to fill out mempool knowledge
2) if txhash is announced, add or remove from set
based on add/remove flag
3) if blockhash is announced, get block txn list,
remove from those transactions local view of mempool
4) if we drop a sequence number, go to (1)
The mempool sequence number starts at the value 1, and
increments each time a transaction enters the mempool,
or is evicted from the mempool for any reason, including
block inclusion. The mempool sequence number is published
via ZMQ for any transaction-related notification.
These features allow for ZMQ/RPC consumer to track mempool
state in a more exacting way, without unnecesarily polling
getrawmempool. See interface_zmq.py::test_mempool_sync for
example usage.
2020-09-04 11:55:58 -04:00
void transactionRemovedFromMempool ( const CTransactionRef & tx , MemPoolRemovalReason reason , uint64_t mempool_sequence ) override ;
2019-04-29 09:52:01 -04:00
void ReacceptWalletTransactions ( ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2019-03-20 19:07:52 -03:00
void ResendWalletTransactions ( ) ;
2019-03-11 17:12:58 -03:00
struct Balance {
CAmount m_mine_trusted { 0 } ; //!< Trusted, at depth=GetBalance.min_depth or more
CAmount m_mine_untrusted_pending { 0 } ; //!< Untrusted, but in mempool (pending)
CAmount m_mine_immature { 0 } ; //!< Immature coinbases in the main chain
CAmount m_watchonly_trusted { 0 } ;
CAmount m_watchonly_untrusted_pending { 0 } ;
CAmount m_watchonly_immature { 0 } ;
} ;
2018-09-13 01:53:19 -03:00
Balance GetBalance ( int min_depth = 0 , bool avoid_reuse = true ) const ;
2017-04-28 15:10:21 -03:00
CAmount GetAvailableBalance ( const CCoinControl * coinControl = nullptr ) const ;
2015-09-14 09:49:59 -03:00
2020-06-27 11:05:41 -04:00
OutputType TransactionChangeType ( const Optional < OutputType > & change_type , const std : : vector < CRecipient > & vecSend ) ;
2018-01-23 13:56:15 -03:00
2015-09-14 09:49:59 -03:00
/**
* Insert additional inputs into the transaction by
* calling CreateTransaction ( ) ;
*/
2020-04-18 15:18:17 -04:00
bool FundTransaction ( CMutableTransaction & tx , CAmount & nFeeRet , int & nChangePosInOut , bilingual_str & error , bool lockUnspents , const std : : set < int > & setSubtractFeeFromOutputs , CCoinControl ) ;
2020-02-10 21:49:56 -03:00
// Fetch the inputs and sign with SIGHASH_ALL.
bool SignTransaction ( CMutableTransaction & tx ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
// Sign the tx given the input coins and sighash.
bool SignTransaction ( CMutableTransaction & tx , const std : : map < COutPoint , Coin > & coins , int sighash , std : : map < int , std : : string > & input_errors ) const ;
2020-02-13 19:09:12 -03:00
SigningResult SignMessage ( const std : : string & message , const PKHash & pkhash , std : : string & str_sig ) const ;
2015-09-14 09:49:59 -03:00
2020-02-10 21:50:56 -03:00
/**
* Fills out a PSBT with information from the wallet . Fills in UTXOs if we have
* them . Tries to sign if sign = true . Sets ` complete ` if the PSBT is now complete
* ( i . e . has all required signatures or signature - parts , and is ready to
* finalize . ) Sets ` error ` and returns false if something goes wrong .
*
* @ param [ in ] psbtx PartiallySignedTransaction to fill in
* @ param [ out ] complete indicates whether the PSBT is now complete
* @ param [ in ] sighash_type the sighash type to use when signing ( if PSBT does not specify )
* @ param [ in ] sign whether to sign or not
* @ param [ in ] bip32derivs whether to fill in bip32 derivation information if available
* return error
*/
TransactionError FillPSBT ( PartiallySignedTransaction & psbtx ,
bool & complete ,
int sighash_type = 1 /* SIGHASH_ALL */ ,
bool sign = true ,
2020-01-31 23:12:14 -03:00
bool bip32derivs = true ,
size_t * n_signed = nullptr ) const ;
2020-02-10 21:50:56 -03:00
2015-09-14 09:49:59 -03:00
/**
* Create a new transaction paying the recipients with a set of coins
* selected by SelectCoins ( ) ; Also create the change output , when needed
2016-03-29 22:04:22 -03:00
* @ note passing nChangePosInOut as - 1 will result in setting a random position
2015-09-14 09:49:59 -03:00
*/
2020-07-12 15:52:02 -04:00
bool CreateTransaction ( 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 ) ;
2019-04-03 18:51:23 -03:00
/**
* Submit the transaction to the node ' s mempool and then relay to peers .
* Should be called after CreateTransaction unless you want to abort
* broadcasting the transaction .
*
2020-01-16 23:23:35 -03:00
* @ param [ in ] tx The transaction to be broadcast .
* @ param [ in ] mapValue key - values to be set on the transaction .
* @ param [ in ] orderForm BIP 70 / BIP 21 order form details to be set on the transaction .
2019-04-03 18:51:23 -03:00
*/
2019-10-18 10:37:40 -03:00
void CommitTransaction ( CTransactionRef tx , mapValue_t mapValue , std : : vector < std : : pair < std : : string , std : : string > > orderForm ) ;
2011-06-26 13:23:24 -04:00
2018-08-07 19:59:53 -04:00
bool DummySignTx ( CMutableTransaction & txNew , const std : : set < CTxOut > & txouts , bool use_max_sig = false ) const
2018-03-05 18:37:24 -03:00
{
std : : vector < CTxOut > v_txouts ( txouts . size ( ) ) ;
std : : copy ( txouts . begin ( ) , txouts . end ( ) , v_txouts . begin ( ) ) ;
2018-08-07 19:59:53 -04:00
return DummySignTx ( txNew , v_txouts , use_max_sig ) ;
2018-03-05 18:37:24 -03:00
}
2018-08-07 19:59:53 -04:00
bool DummySignTx ( CMutableTransaction & txNew , const std : : vector < CTxOut > & txouts , bool use_max_sig = false ) const ;
bool DummySignInput ( CTxIn & tx_in , const CTxOut & txout , bool use_max_sig = false ) const ;
2015-10-19 06:19:38 -03:00
2019-06-27 21:17:42 -04:00
bool ImportScripts ( const std : : set < CScript > scripts , int64_t timestamp ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2019-04-04 06:12:50 -03:00
bool ImportPrivKeys ( const std : : map < CKeyID , CKey > & privkey_map , const int64_t timestamp ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
bool ImportPubKeys ( const std : : vector < CKeyID > & ordered_pubkeys , const std : : map < CKeyID , CPubKey > & pubkey_map , const std : : map < CKeyID , std : : pair < CPubKey , KeyOriginInfo > > & key_origins , const bool add_keypool , const bool internal , const int64_t timestamp ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2019-07-11 20:21:05 -04:00
bool ImportScriptPubKeys ( const std : : string & label , const std : : set < CScript > & script_pub_keys , const bool have_solving_data , const bool apply_label , const int64_t timestamp ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2019-04-04 06:12:50 -03:00
2018-04-07 13:12:46 -03:00
CFeeRate m_pay_tx_fee { DEFAULT_PAY_TX_FEE } ;
unsigned int m_confirm_target { DEFAULT_TX_CONFIRM_TARGET } ;
bool m_spend_zero_conf_change { DEFAULT_SPEND_ZEROCONF_CHANGE } ;
bool m_signal_rbf { DEFAULT_WALLET_RBF } ;
2019-08-01 16:39:46 -04:00
bool m_allow_fallback_fee { true } ; //!< will be false if -fallbackfee=0
2018-04-07 13:12:46 -03:00
CFeeRate m_min_fee { DEFAULT_TRANSACTION_MINFEE } ; //!< Override with -mintxfee
/**
* If fee estimation does not have enough data to provide estimates , use this fee instead .
* Has no effect if not using fee estimation
* Override with - fallbackfee
*/
CFeeRate m_fallback_fee { DEFAULT_FALLBACK_FEE } ;
CFeeRate m_discard_rate { DEFAULT_DISCARD_FEE } ;
2018-10-25 21:36:56 -03:00
CAmount m_max_aps_fee { DEFAULT_MAX_AVOIDPARTIALSPEND_FEE } ; //!< note: this is absolute fee, not fee rate
2018-02-10 23:06:35 -03:00
OutputType m_default_address_type { DEFAULT_ADDRESS_TYPE } ;
2020-06-27 11:05:41 -04:00
/**
* Default output type for change outputs . When unset , automatically choose type
* based on address type setting and the types other of non - change outputs
* ( see - changetype option documentation and implementation in
* CWallet : : TransactionChangeType for details ) .
*/
Optional < OutputType > m_default_change_type { } ;
2019-02-20 15:45:16 -03:00
/** Absolute maximum transaction fee (in satoshis) used by default for the wallet */
CAmount m_default_max_tx_fee { DEFAULT_TRANSACTION_MAXFEE } ;
2014-05-27 15:44:57 -04:00
2020-03-02 04:33:45 -03:00
size_t KeypoolCountExternalKeys ( ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2013-06-25 16:07:29 -04:00
bool TopUpKeyPool ( unsigned int kpSize = 0 ) ;
2018-05-16 21:56:41 -04:00
2020-03-02 04:54:59 -03:00
int64_t GetOldestKeyPoolTime ( ) const ;
2011-06-26 13:23:24 -04:00
2020-03-02 05:17:33 -03:00
std : : set < std : : set < CTxDestination > > GetAddressGroupings ( ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2019-12-18 19:46:53 -03:00
std : : map < CTxDestination , CAmount > GetAddressBalances ( ) const ;
2012-08-01 12:48:42 -04:00
2017-10-20 14:27:55 -03:00
std : : set < CTxDestination > GetLabelAddresses ( const std : : string & label ) const ;
2013-07-15 19:01:09 -04:00
2019-12-31 15:55:18 -03:00
/**
* Marks all outputs in each one of the destinations dirty , so their cache is
* reset and does not return outdated information .
*/
void MarkDestinationsDirty ( const std : : set < CTxDestination > & destinations ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2019-06-18 15:19:13 -04:00
bool GetNewDestination ( const OutputType type , const std : : string label , CTxDestination & dest , std : : string & error ) ;
2019-06-18 15:49:02 -04:00
bool GetNewChangeDestination ( const OutputType type , CTxDestination & dest , std : : string & error ) ;
2019-06-18 15:19:13 -04:00
2020-06-15 18:03:17 -04:00
isminetype IsMine ( const CTxDestination & dest ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
isminetype IsMine ( const CScript & script ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
isminetype IsMine ( const CTxIn & txin ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2016-12-09 17:31:06 -03:00
/**
* Returns amount of debit if the input matches the
* filter , otherwise returns 0
*/
2014-04-22 19:46:19 -03:00
CAmount GetDebit ( const CTxIn & txin , const isminefilter & filter ) const ;
2020-06-15 18:03:17 -04:00
isminetype IsMine ( const CTxOut & txout ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2015-02-04 19:19:29 -03:00
CAmount GetCredit ( const CTxOut & txout , const isminefilter & filter ) const ;
2020-08-20 19:28:10 -04:00
bool IsChange ( const CTxOut & txout ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
bool IsChange ( const CScript & script ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
CAmount GetChange ( const CTxOut & txout ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2020-06-15 18:03:17 -04:00
bool IsMine ( const CTransaction & tx ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2014-12-18 22:03:51 -03:00
/** should probably be renamed to IsRelevantToMe */
2015-02-04 19:19:29 -03:00
bool IsFromMe ( const CTransaction & tx ) const ;
CAmount GetDebit ( const CTransaction & tx , const isminefilter & filter ) const ;
2016-12-09 17:31:06 -03:00
/** Returns whether all of the inputs match the filter */
bool IsAllFromMe ( const CTransaction & tx , const isminefilter & filter ) const ;
2015-02-04 19:19:29 -03:00
CAmount GetCredit ( const CTransaction & tx , const isminefilter & filter ) const ;
CAmount GetChange ( const CTransaction & tx ) const ;
2020-02-26 18:05:49 -03:00
void chainStateFlushed ( const CBlockLocator & loc ) override ;
2011-06-26 13:23:24 -04:00
2014-12-18 22:03:51 -03:00
DBErrors LoadWallet ( bool & fFirstRunRet ) ;
2018-04-25 18:16:16 -03:00
DBErrors ZapSelectTx ( std : : vector < uint256 > & vHashIn , std : : vector < uint256 > & vHashOut ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2011-06-26 13:23:24 -04:00
2014-12-18 22:03:51 -03:00
bool SetAddressBook ( const CTxDestination & address , const std : : string & strName , const std : : string & purpose ) ;
2012-05-27 19:06:09 -04:00
2014-12-18 22:03:51 -03:00
bool DelAddressBook ( const CTxDestination & address ) ;
2012-05-28 14:45:12 -04:00
2019-10-07 15:11:34 -03:00
unsigned int GetKeyPoolSize ( ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2011-06-28 17:45:22 -04:00
2014-12-18 22:03:51 -03:00
//! signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
2019-10-07 15:11:34 -03:00
void SetMinVersion ( enum WalletFeature , WalletBatch * batch_in = nullptr , bool fExplicit = false ) override ;
2011-06-26 13:23:24 -04:00
2014-12-18 22:03:51 -03:00
//! change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format)
bool SetMaxVersion ( int nVersion ) ;
2011-06-26 13:23:24 -04:00
2014-12-18 22:03:51 -03:00
//! get the current wallet format (the oldest client version guaranteed to understand this wallet)
2020-03-02 05:17:33 -03:00
int GetVersion ( ) const { LOCK ( cs_wallet ) ; return nWalletVersion ; }
2011-06-26 13:23:24 -04:00
2014-12-18 22:03:51 -03:00
//! Get wallet transactions that conflict with given transaction (spend same outputs)
2018-08-26 16:48:03 -03:00
std : : set < uint256 > GetConflicts ( const uint256 & txid ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2011-06-26 13:23:24 -04:00
2016-12-09 15:45:27 -03:00
//! Check if a given transaction has any of its outputs spent by another transaction in the wallet
2018-04-25 18:16:16 -03:00
bool HasWalletSpend ( const uint256 & txid ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2016-12-09 15:45:27 -03:00
2015-02-04 17:19:27 -03:00
//! Flush wallet (bitdb flush)
2020-06-15 17:59:24 -04:00
void Flush ( ) ;
//! Close wallet database
void Close ( ) ;
2015-02-04 17:19:27 -03:00
2018-04-28 18:36:43 -03:00
/** Wallet is about to be unloaded */
boost : : signals2 : : signal < void ( ) > NotifyUnload ;
2018-04-17 14:22:23 -03:00
/**
2014-12-18 22:03:51 -03:00
* Address book entry changed .
* @ note called with lock cs_wallet held .
*/
boost : : signals2 : : signal < void ( CWallet * wallet , const CTxDestination
& address , const std : : string & label , bool isMine ,
const std : : string & purpose ,
ChangeType status ) > NotifyAddressBookChanged ;
2011-06-26 13:23:24 -04:00
2018-04-17 14:22:23 -03:00
/**
2014-12-18 22:03:51 -03:00
* Wallet transaction added , removed or updated .
* @ note called with lock cs_wallet held .
*/
boost : : signals2 : : signal < void ( CWallet * wallet , const uint256 & hashTx ,
ChangeType status ) > NotifyTransactionChanged ;
2011-06-26 13:23:24 -04:00
2014-12-18 22:03:51 -03:00
/** Show progress e.g. for rescan */
boost : : signals2 : : signal < void ( const std : : string & title , int nProgress ) > ShowProgress ;
2014-02-13 22:12:51 -03:00
2014-12-18 22:03:51 -03:00
/** Watch-only address added */
boost : : signals2 : : signal < void ( bool fHaveWatchOnly ) > NotifyWatchonlyChanged ;
2015-03-27 06:34:48 -03:00
2019-01-18 19:05:32 -03:00
/** Keypool has new keys */
boost : : signals2 : : signal < void ( ) > NotifyCanGetAddressesChanged ;
2019-06-06 17:58:21 -04:00
/**
* Wallet status ( encrypted , locked ) changed .
* Note : Called without locks held .
*/
boost : : signals2 : : signal < void ( CWallet * wallet ) > NotifyStatusChanged ;
2015-03-27 06:34:48 -03:00
/** Inquire whether this wallet broadcasts transactions. */
bool GetBroadcastTransactions ( ) const { return fBroadcastTransactions ; }
/** Set whether this wallet broadcasts transactions. */
void SetBroadcastTransactions ( bool broadcast ) { fBroadcastTransactions = broadcast ; }
2016-01-07 18:31:27 -03:00
2017-04-28 15:10:21 -03:00
/** Return whether transaction can be abandoned */
bool TransactionCanBeAbandoned ( const uint256 & hashTx ) const ;
2016-01-07 18:31:27 -03:00
/* Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent. */
2019-04-29 09:52:01 -04:00
bool AbandonTransaction ( const uint256 & hashTx ) ;
2016-02-22 06:48:44 -03:00
2016-12-09 15:45:27 -03:00
/** Mark a transaction as replaced by another transaction (e.g., BIP 125). */
bool MarkReplaced ( const uint256 & originalHash , const uint256 & newHash ) ;
2016-03-15 06:30:37 -03:00
/* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */
2020-08-04 20:45:28 -04:00
static std : : shared_ptr < CWallet > Create ( interfaces : : Chain & chain , const std : : string & name , std : : unique_ptr < WalletDatabase > database , uint64_t wallet_creation_flags , bilingual_str & error , std : : vector < bilingual_str > & warnings ) ;
2016-03-15 06:30:37 -03:00
2016-10-20 04:22:13 -03:00
/**
* Wallet post - init setup
* Gives the wallet a chance to register repetitive tasks and complete post - init tasks
*/
2018-04-19 18:42:40 -03:00
void postInitProcess ( ) ;
2016-10-20 04:22:13 -03:00
2020-03-02 05:23:34 -03:00
bool BackupWallet ( const std : : string & strDest ) const ;
2016-01-02 08:34:08 -03:00
2016-08-17 09:09:47 -03:00
/* Returns true if HD is enabled */
2017-03-08 23:32:02 -03:00
bool IsHDEnabled ( ) const ;
2016-08-17 09:09:47 -03:00
2019-02-06 23:26:55 -03:00
/* Returns true if the wallet can give out new addresses. This means it has keys in the keypool or can generate new keys */
2020-03-02 04:35:58 -03:00
bool CanGetAddresses ( bool internal = false ) const ;
2019-02-06 23:26:55 -03:00
2017-01-17 20:06:16 -03:00
/**
* Blocks until the wallet state is up - to - date to / at least / the current
* chain at the time this function is entered
* Obviously holding cs_main / cs_wallet when going into this call may cause
* deadlock
*/
2020-08-05 12:55:31 -04:00
void BlockUntilSyncedToCurrentChain ( ) const EXCLUSIVE_LOCKS_REQUIRED ( ! : : cs_main , ! cs_wallet ) ;
2017-11-30 21:49:11 -03:00
2017-02-16 10:22:18 -03:00
/** set a single wallet flag */
2019-10-29 18:49:39 -03:00
void SetWalletFlag ( uint64_t flags ) ;
2017-02-16 10:22:18 -03:00
2019-02-06 23:26:55 -03:00
/** Unsets a single wallet flag */
void UnsetWalletFlag ( uint64_t flag ) ;
2017-02-16 10:22:18 -03:00
/** check if a certain wallet flag is set */
2019-10-07 15:11:34 -03:00
bool IsWalletFlagSet ( uint64_t flag ) const override ;
2017-02-16 10:22:18 -03:00
2017-05-05 03:53:39 -03:00
/** overwrite all flags by the given uint64_t
returns false if unknown , non - tolerable flags are present */
2020-05-21 23:15:41 -04:00
bool AddWalletFlags ( uint64_t flags ) ;
/** Loads the flags into the wallet. (used by LoadWallet) */
bool LoadWalletFlags ( uint64_t flags ) ;
2018-06-15 19:02:52 -04:00
2019-08-14 14:25:53 -04:00
/** Determine if we are a legacy wallet */
bool IsLegacy ( ) const ;
2018-06-15 19:02:52 -04:00
/** Returns a bracketed wallet name for displaying in logs, will return [default wallet] if the wallet has no name */
2019-10-07 15:11:34 -03:00
const std : : string GetDisplayName ( ) const override {
2018-06-15 19:02:52 -04:00
std : : string wallet_name = GetName ( ) . length ( ) = = 0 ? " default wallet " : GetName ( ) ;
return strprintf ( " [%s] " , wallet_name ) ;
} ;
/** Prepends the wallet name in logging output to ease debugging in multi-wallet use cases */
template < typename . . . Params >
void WalletLogPrintf ( std : : string fmt , Params . . . parameters ) const {
LogPrintf ( ( " %s " + fmt ) . c_str ( ) , GetDisplayName ( ) , parameters . . . ) ;
} ;
2019-04-06 13:55:34 -03:00
/** Upgrade the wallet */
2019-08-19 18:12:35 -04:00
bool UpgradeWallet ( int version , bilingual_str & error , std : : vector < bilingual_str > & warnings ) ;
2019-04-06 13:55:34 -03:00
2019-10-07 15:11:34 -03:00
//! Returns all unique ScriptPubKeyMans in m_internal_spk_managers and m_external_spk_managers
std : : set < ScriptPubKeyMan * > GetActiveScriptPubKeyMans ( ) const ;
//! Returns all unique ScriptPubKeyMans
std : : set < ScriptPubKeyMan * > GetAllScriptPubKeyMans ( ) const ;
//! Get the ScriptPubKeyMan for the given OutputType and internal/external chain.
ScriptPubKeyMan * GetScriptPubKeyMan ( const OutputType & type , bool internal ) const ;
2019-10-07 15:11:34 -03:00
//! Get the ScriptPubKeyMan for a script
ScriptPubKeyMan * GetScriptPubKeyMan ( const CScript & script ) const ;
2019-10-07 15:11:34 -03:00
//! Get the ScriptPubKeyMan by id
ScriptPubKeyMan * GetScriptPubKeyMan ( const uint256 & id ) const ;
2019-10-07 15:11:34 -03:00
2020-02-10 21:49:56 -03:00
//! Get all of the ScriptPubKeyMans for a script given additional information in sigdata (populated by e.g. a psbt)
std : : set < ScriptPubKeyMan * > GetScriptPubKeyMans ( const CScript & script , SignatureData & sigdata ) const ;
2019-10-07 15:11:34 -03:00
//! Get the SigningProvider for a script
2020-02-10 23:27:59 -03:00
std : : unique_ptr < SigningProvider > GetSolvingProvider ( const CScript & script ) const ;
std : : unique_ptr < SigningProvider > GetSolvingProvider ( const CScript & script , SignatureData & sigdata ) const ;
2019-10-07 15:11:34 -03:00
2019-10-07 15:11:34 -03:00
//! Get the LegacyScriptPubKeyMan which is used for all types, internal, and external.
2019-10-07 15:11:34 -03:00
LegacyScriptPubKeyMan * GetLegacyScriptPubKeyMan ( ) const ;
2019-10-07 15:11:34 -03:00
LegacyScriptPubKeyMan * GetOrCreateLegacyScriptPubKeyMan ( ) ;
//! Make a LegacyScriptPubKeyMan and set it for all types, internal, and external.
void SetupLegacyScriptPubKeyMan ( ) ;
2019-10-07 15:11:34 -03:00
2019-12-05 20:01:30 -03:00
const CKeyingMaterial & GetEncryptionKey ( ) const override ;
bool HasEncryptionKeys ( ) const override ;
2019-04-20 12:02:52 -04:00
/** Get last block processed height */
int GetLastBlockHeight ( ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet )
{
AssertLockHeld ( cs_wallet ) ;
assert ( m_last_block_processed_height > = 0 ) ;
return m_last_block_processed_height ;
} ;
2020-01-16 17:56:58 -03:00
uint256 GetLastBlockHash ( ) const EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet )
{
AssertLockHeld ( cs_wallet ) ;
assert ( m_last_block_processed_height > = 0 ) ;
return m_last_block_processed ;
}
2019-04-20 12:02:52 -04:00
/** Set last block processed height, currently only use in unit test */
void SetLastBlockProcessed ( int block_height , uint256 block_hash ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet )
{
AssertLockHeld ( cs_wallet ) ;
m_last_block_processed_height = block_height ;
m_last_block_processed = block_hash ;
} ;
2019-10-07 15:11:34 -03:00
//! Connect the signals from ScriptPubKeyMans to the signals in CWallet
void ConnectScriptPubKeyManNotifiers ( ) ;
2019-07-08 15:41:31 -04:00
//! Instantiate a descriptor ScriptPubKeyMan from the WalletDescriptor and load it
void LoadDescriptorScriptPubKeyMan ( uint256 id , WalletDescriptor & desc ) ;
2020-05-21 23:01:24 -04:00
//! Adds the active ScriptPubKeyMan for the specified type and internal. Writes it to the wallet file
2019-07-08 15:41:31 -04:00
//! @param[in] id The unique id for the ScriptPubKeyMan
//! @param[in] type The OutputType this ScriptPubKeyMan provides addresses for
//! @param[in] internal Whether this ScriptPubKeyMan provides change addresses
2020-05-21 23:01:24 -04:00
void AddActiveScriptPubKeyMan ( uint256 id , OutputType type , bool internal ) ;
//! Loads an active ScriptPubKeyMan for the specified type and internal. (used by LoadWallet)
//! @param[in] id The unique id for the ScriptPubKeyMan
//! @param[in] type The OutputType this ScriptPubKeyMan provides addresses for
//! @param[in] internal Whether this ScriptPubKeyMan provides change addresses
void LoadActiveScriptPubKeyMan ( uint256 id , OutputType type , bool internal ) ;
2019-07-11 18:21:21 -04:00
//! Create new DescriptorScriptPubKeyMans and add them to the wallet
2020-08-05 08:00:50 -04:00
void SetupDescriptorScriptPubKeyMans ( ) EXCLUSIVE_LOCKS_REQUIRED ( cs_wallet ) ;
2019-08-01 18:08:47 -04:00
//! Return the DescriptorScriptPubKeyMan for a WalletDescriptor if it is already in the wallet
DescriptorScriptPubKeyMan * GetDescriptorScriptPubKeyMan ( const WalletDescriptor & desc ) const ;
//! Add a descriptor to the wallet, return a ScriptPubKeyMan & associated output type
ScriptPubKeyMan * AddWalletDescriptor ( WalletDescriptor & desc , const FlatSigningProvider & signing_provider , const std : : string & label ) ;
2011-06-26 13:23:24 -04:00
} ;
2019-03-20 18:46:38 -03:00
/**
* Called periodically by the schedule thread . Prompts individual wallets to resend
* their transactions . Actual rebroadcast schedule is managed by the wallets themselves .
*/
void MaybeResendWalletTxs ( ) ;
2017-12-08 18:07:37 -03:00
/** RAII object to check and reserve a wallet rescan */
class WalletRescanReserver
{
private :
2020-04-11 19:42:15 -04:00
CWallet & m_wallet ;
2017-12-08 18:07:37 -03:00
bool m_could_reserve ;
public :
2020-04-11 19:42:15 -04:00
explicit WalletRescanReserver ( CWallet & w ) : m_wallet ( w ) , m_could_reserve ( false ) { }
2017-12-08 18:07:37 -03:00
bool reserve ( )
{
assert ( ! m_could_reserve ) ;
2019-05-30 00:02:41 -04:00
if ( m_wallet . fScanningWallet . exchange ( true ) ) {
2017-12-08 18:07:37 -03:00
return false ;
}
2020-04-11 19:42:15 -04:00
m_wallet . m_scanning_start = GetTimeMillis ( ) ;
m_wallet . m_scanning_progress = 0 ;
2017-12-08 18:07:37 -03:00
m_could_reserve = true ;
return true ;
}
2017-12-12 20:13:58 -03:00
bool isReserved ( ) const
{
2020-04-11 19:42:15 -04:00
return ( m_could_reserve & & m_wallet . fScanningWallet ) ;
2017-12-12 20:13:58 -03:00
}
2017-12-08 18:07:37 -03:00
~ WalletRescanReserver ( )
{
if ( m_could_reserve ) {
2020-04-11 19:42:15 -04:00
m_wallet . fScanningWallet = false ;
2017-12-08 18:07:37 -03:00
}
}
} ;
2018-03-05 18:37:24 -03:00
// Calculate the size of the transaction assuming all signatures are max size
2018-07-14 22:19:44 -04:00
// Use DummySignatureCreator, which inserts 71 byte signatures everywhere.
2018-03-05 18:37:24 -03:00
// NOTE: this requires that all inputs must be in mapWallet (eg the tx should
// be IsAllFromMe).
2018-08-26 16:48:03 -03:00
int64_t CalculateMaximumSignedTxSize ( const CTransaction & tx , const CWallet * wallet , bool use_max_sig = false ) EXCLUSIVE_LOCKS_REQUIRED ( wallet - > cs_wallet ) ;
2018-08-07 19:59:53 -04:00
int64_t CalculateMaximumSignedTxSize ( const CTransaction & tx , const CWallet * wallet , const std : : vector < CTxOut > & txouts , bool use_max_sig = false ) ;
2020-08-17 15:21:50 -04:00
//! Add wallet name to persistent configuration so it will be loaded on startup.
bool AddWalletSetting ( interfaces : : Chain & chain , const std : : string & wallet_name ) ;
//! Remove wallet name from persistent configuration so it will not be loaded on startup.
bool RemoveWalletSetting ( interfaces : : Chain & chain , const std : : string & wallet_name ) ;
2015-03-21 14:15:31 -03:00
# endif // BITCOIN_WALLET_WALLET_H