2017-04-17 15:10:47 -04:00
// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2018-04-07 03:42:02 -04:00
# include <interfaces/wallet.h>
2017-04-17 15:10:47 -04:00
2017-04-17 18:56:44 -04:00
# include <amount.h>
# include <consensus/validation.h>
2017-05-30 15:55:17 -04:00
# include <interfaces/chain.h>
2018-04-07 03:42:02 -04:00
# include <interfaces/handler.h>
2018-04-07 12:12:46 -04:00
# include <policy/feerate.h>
# include <policy/fees.h>
2017-04-17 18:56:44 -04:00
# include <primitives/transaction.h>
# include <script/standard.h>
# include <support/allocators/secure.h>
# include <sync.h>
# include <ui_interface.h>
# include <uint256.h>
2017-05-30 15:55:17 -04:00
# include <util/system.h>
2017-04-17 18:56:44 -04:00
# include <wallet/feebumper.h>
2018-04-07 12:12:46 -04:00
# include <wallet/fees.h>
2019-06-06 09:53:16 +02:00
# include <wallet/ismine.h>
2017-09-28 14:13:29 -04:00
# include <wallet/rpcwallet.h>
2019-04-02 17:11:26 -04:00
# include <wallet/load.h>
2017-04-17 15:10:47 -04:00
# include <wallet/wallet.h>
2017-09-28 14:13:29 -04:00
# include <wallet/walletutil.h>
2017-04-17 15:10:47 -04:00
2017-05-30 15:55:17 -04:00
# include <memory>
# include <string>
# include <utility>
# include <vector>
2017-04-17 15:10:47 -04:00
2018-04-07 03:42:02 -04:00
namespace interfaces {
2017-04-17 15:10:47 -04:00
namespace {
2017-04-18 16:42:30 -04:00
//! Construct wallet tx struct.
2017-07-31 15:30:21 -04:00
WalletTx MakeWalletTx ( interfaces : : Chain : : Lock & locked_chain , CWallet & wallet , const CWalletTx & wtx )
2017-04-18 16:42:30 -04:00
{
WalletTx result ;
result . tx = wtx . tx ;
result . txin_is_mine . reserve ( wtx . tx - > vin . size ( ) ) ;
2018-12-15 22:07:28 +00:00
result . txin_issuance_asset . resize ( wtx . tx - > vin . size ( ) ) ;
result . txin_issuance_token . resize ( wtx . tx - > vin . size ( ) ) ;
for ( unsigned int i = 0 ; i < wtx . tx - > vin . size ( ) ; + + i ) {
const auto & txin = wtx . tx - > vin [ i ] ;
2017-04-18 16:42:30 -04:00
result . txin_is_mine . emplace_back ( wallet . IsMine ( txin ) ) ;
2018-12-15 22:07:28 +00:00
wtx . GetIssuanceAssets ( i , & result . txin_issuance_asset [ i ] , & result . txin_issuance_token [ i ] ) ;
result . txin_issuance_asset_amount . emplace_back ( wtx . GetIssuanceAmount ( i , false ) ) ;
result . txin_issuance_token_amount . emplace_back ( wtx . GetIssuanceAmount ( i , true ) ) ;
2017-04-18 16:42:30 -04:00
}
result . txout_is_mine . reserve ( wtx . tx - > vout . size ( ) ) ;
result . txout_address . reserve ( wtx . tx - > vout . size ( ) ) ;
result . txout_address_is_mine . reserve ( wtx . tx - > vout . size ( ) ) ;
for ( const auto & txout : wtx . tx - > vout ) {
result . txout_is_mine . emplace_back ( wallet . IsMine ( txout ) ) ;
result . txout_address . emplace_back ( ) ;
result . txout_address_is_mine . emplace_back ( ExtractDestination ( txout . scriptPubKey , result . txout_address . back ( ) ) ?
IsMine ( wallet , result . txout_address . back ( ) ) :
ISMINE_NO ) ;
2019-04-11 14:47:14 -04:00
result . txout_is_change . push_back ( wallet . IsChange ( txout ) ) ;
2017-04-18 16:42:30 -04:00
}
2018-03-01 18:20:17 +00:00
// ELEMENTS: Retrieve unblinded information about outputs
for ( unsigned int i = 0 ; i < wtx . tx - > vout . size ( ) ; + + i ) {
result . txout_amounts . emplace_back ( wtx . GetOutputValueOut ( i ) ) ;
result . txout_assets . emplace_back ( wtx . GetOutputAsset ( i ) ) ;
}
2017-07-31 15:30:21 -04:00
result . credit = wtx . GetCredit ( locked_chain , ISMINE_ALL ) ;
2017-04-18 16:42:30 -04:00
result . debit = wtx . GetDebit ( ISMINE_ALL ) ;
result . change = wtx . GetChange ( ) ;
result . time = wtx . GetTxTime ( ) ;
result . value_map = wtx . mapValue ;
result . is_coinbase = wtx . IsCoinBase ( ) ;
return result ;
}
//! Construct wallet tx status struct.
2017-07-31 15:30:21 -04:00
WalletTxStatus MakeWalletTxStatus ( interfaces : : Chain : : Lock & locked_chain , const CWalletTx & wtx )
2017-04-18 16:42:30 -04:00
{
WalletTxStatus result ;
2019-03-06 16:47:57 -05:00
result . block_height = locked_chain . getBlockHeight ( wtx . hashBlock ) . get_value_or ( std : : numeric_limits < int > : : max ( ) ) ;
2017-07-31 15:30:21 -04:00
result . blocks_to_maturity = wtx . GetBlocksToMaturity ( locked_chain ) ;
result . depth_in_main_chain = wtx . GetDepthInMainChain ( locked_chain ) ;
2017-04-18 16:42:30 -04:00
result . time_received = wtx . nTimeReceived ;
result . lock_time = wtx . tx - > nLockTime ;
2017-07-28 18:13:23 -04:00
result . is_final = locked_chain . checkFinalTx ( * wtx . tx ) ;
2017-07-31 15:30:21 -04:00
result . is_trusted = wtx . IsTrusted ( locked_chain ) ;
2017-04-18 16:42:30 -04:00
result . is_abandoned = wtx . isAbandoned ( ) ;
result . is_coinbase = wtx . IsCoinBase ( ) ;
2017-07-31 15:30:21 -04:00
result . is_in_main_chain = wtx . IsInMainChain ( locked_chain ) ;
2017-04-18 16:42:30 -04:00
return result ;
}
2017-04-17 19:46:08 -04:00
//! Construct wallet TxOut struct.
2017-07-31 15:30:21 -04:00
WalletTxOut MakeWalletTxOut ( interfaces : : Chain : : Lock & locked_chain ,
CWallet & wallet ,
const CWalletTx & wtx ,
int n ,
int depth ) EXCLUSIVE_LOCKS_REQUIRED ( wallet . cs_wallet )
2017-04-17 19:46:08 -04:00
{
WalletTxOut result ;
result . txout = wtx . tx - > vout [ n ] ;
result . time = wtx . GetTxTime ( ) ;
result . depth_in_main_chain = depth ;
2017-07-31 15:30:21 -04:00
result . is_spent = wallet . IsSpent ( locked_chain , wtx . GetHash ( ) , n ) ;
2017-04-17 19:46:08 -04:00
return result ;
}
2017-04-17 15:10:47 -04:00
class WalletImpl : public Wallet
{
public :
2019-02-21 15:26:29 +00:00
explicit WalletImpl ( const std : : shared_ptr < CWallet > & wallet ) : m_wallet ( wallet ) { }
2017-04-17 15:10:47 -04:00
2017-04-17 18:56:44 -04:00
bool encryptWallet ( const SecureString & wallet_passphrase ) override
{
2019-02-21 15:26:29 +00:00
return m_wallet - > EncryptWallet ( wallet_passphrase ) ;
2017-04-17 18:56:44 -04:00
}
2019-02-21 15:26:29 +00:00
bool isCrypted ( ) override { return m_wallet - > IsCrypted ( ) ; }
bool lock ( ) override { return m_wallet - > Lock ( ) ; }
bool unlock ( const SecureString & wallet_passphrase ) override { return m_wallet - > Unlock ( wallet_passphrase ) ; }
bool isLocked ( ) override { return m_wallet - > IsLocked ( ) ; }
2017-04-17 18:56:44 -04:00
bool changeWalletPassphrase ( const SecureString & old_wallet_passphrase ,
const SecureString & new_wallet_passphrase ) override
{
2019-02-21 15:26:29 +00:00
return m_wallet - > ChangeWalletPassphrase ( old_wallet_passphrase , new_wallet_passphrase ) ;
2017-04-17 18:56:44 -04:00
}
2019-02-21 15:26:29 +00:00
void abortRescan ( ) override { m_wallet - > AbortRescan ( ) ; }
bool backupWallet ( const std : : string & filename ) override { return m_wallet - > BackupWallet ( filename ) ; }
std : : string getWalletName ( ) override { return m_wallet - > GetName ( ) ; }
2020-11-09 03:58:21 +00:00
bool getNewDestination ( const OutputType type , const std : : string label , CTxDestination & dest , bool add_blinding_key = false ) override
2017-04-18 13:01:23 -04:00
{
2019-06-18 15:19:13 -04:00
LOCK ( m_wallet - > cs_wallet ) ;
std : : string error ;
2020-11-09 03:58:21 +00:00
return m_wallet - > GetNewDestination ( type , label , dest , error , add_blinding_key ) ;
2017-04-18 13:01:23 -04:00
}
2019-02-21 15:26:29 +00:00
bool getPubKey ( const CKeyID & address , CPubKey & pub_key ) override { return m_wallet - > GetPubKey ( address , pub_key ) ; }
bool getPrivKey ( const CKeyID & address , CKey & key ) override { return m_wallet - > GetKey ( address , key ) ; }
bool isSpendable ( const CTxDestination & dest ) override { return IsMine ( * m_wallet , dest ) & ISMINE_SPENDABLE ; }
bool haveWatchOnly ( ) override { return m_wallet - > HaveWatchOnly ( ) ; } ;
2017-04-17 18:56:44 -04:00
bool setAddressBook ( const CTxDestination & dest , const std : : string & name , const std : : string & purpose ) override
{
2019-02-21 15:26:29 +00:00
return m_wallet - > SetAddressBook ( dest , name , purpose ) ;
2017-04-17 18:56:44 -04:00
}
2017-04-18 13:01:23 -04:00
bool delAddressBook ( const CTxDestination & dest ) override
{
2019-02-21 15:26:29 +00:00
return m_wallet - > DelAddressBook ( dest ) ;
2017-04-18 13:01:23 -04:00
}
2018-04-10 11:50:10 -04:00
bool getAddress ( const CTxDestination & dest ,
std : : string * name ,
isminetype * is_mine ,
std : : string * purpose ) override
2017-04-17 18:56:44 -04:00
{
2019-02-21 15:26:29 +00:00
LOCK ( m_wallet - > cs_wallet ) ;
auto it = m_wallet - > mapAddressBook . find ( dest ) ;
if ( it = = m_wallet - > mapAddressBook . end ( ) ) {
2017-04-17 18:56:44 -04:00
return false ;
}
if ( name ) {
* name = it - > second . name ;
}
if ( is_mine ) {
2019-02-21 15:26:29 +00:00
* is_mine = IsMine ( * m_wallet , dest ) ;
2017-04-17 18:56:44 -04:00
}
2018-04-10 11:50:10 -04:00
if ( purpose ) {
* purpose = it - > second . purpose ;
}
2017-04-17 18:56:44 -04:00
return true ;
}
2017-04-18 13:01:23 -04:00
std : : vector < WalletAddress > getAddresses ( ) override
{
2019-02-21 15:26:29 +00:00
LOCK ( m_wallet - > cs_wallet ) ;
2017-04-18 13:01:23 -04:00
std : : vector < WalletAddress > result ;
2019-02-21 15:26:29 +00:00
for ( const auto & item : m_wallet - > mapAddressBook ) {
result . emplace_back ( item . first , IsMine ( * m_wallet , item . first ) , item . second . name , item . second . purpose ) ;
2017-04-18 13:01:23 -04:00
}
return result ;
}
2019-05-17 16:43:38 +01:00
void learnRelatedScripts ( const CPubKey & key , OutputType type ) override { m_wallet - > LearnRelatedScripts ( key , type ) ; }
2017-04-17 18:56:44 -04:00
bool addDestData ( const CTxDestination & dest , const std : : string & key , const std : : string & value ) override
{
2019-02-21 15:26:29 +00:00
LOCK ( m_wallet - > cs_wallet ) ;
return m_wallet - > AddDestData ( dest , key , value ) ;
2017-04-17 18:56:44 -04:00
}
bool eraseDestData ( const CTxDestination & dest , const std : : string & key ) override
{
2019-02-21 15:26:29 +00:00
LOCK ( m_wallet - > cs_wallet ) ;
return m_wallet - > EraseDestData ( dest , key ) ;
2017-04-17 18:56:44 -04:00
}
std : : vector < std : : string > getDestValues ( const std : : string & prefix ) override
{
2019-02-21 15:26:29 +00:00
LOCK ( m_wallet - > cs_wallet ) ;
return m_wallet - > GetDestValues ( prefix ) ;
2017-04-17 18:56:44 -04:00
}
void lockCoin ( const COutPoint & output ) override
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
return m_wallet - > LockCoin ( output ) ;
2017-04-17 18:56:44 -04:00
}
void unlockCoin ( const COutPoint & output ) override
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
return m_wallet - > UnlockCoin ( output ) ;
2017-04-17 18:56:44 -04:00
}
bool isLockedCoin ( const COutPoint & output ) override
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
return m_wallet - > IsLockedCoin ( output . hash , output . n ) ;
2017-04-17 18:56:44 -04:00
}
void listLockedCoins ( std : : vector < COutPoint > & outputs ) override
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
return m_wallet - > ListLockedCoins ( outputs ) ;
2017-04-17 18:56:44 -04:00
}
2019-07-18 12:06:23 -04:00
CTransactionRef createTransaction ( const std : : vector < CRecipient > & recipients ,
2017-04-17 18:56:44 -04:00
const CCoinControl & coin_control ,
bool sign ,
int & change_pos ,
CAmount & fee ,
2019-04-09 13:29:31 -04:00
std : : vector < CAmount > & out_amounts ,
2017-04-17 18:56:44 -04:00
std : : string & fail_reason ) override
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
2019-07-18 12:06:23 -04:00
CTransactionRef tx ;
if ( ! m_wallet - > CreateTransaction ( * locked_chain , recipients , tx , fee , change_pos ,
2017-04-17 18:56:44 -04:00
fail_reason , coin_control , sign ) ) {
return { } ;
}
2020-11-09 21:20:08 +00:00
// FIXME this obviously-broken logic matches the state of the codebase after 0.18 rebase and was fixed in #693 (Sep 2019) which we will get to before the 0.19 branchpoint, I promise --asp
BlindDetails blind_details ;
out_amounts = blind_details . o_amounts ;
2019-07-18 12:06:23 -04:00
return tx ;
}
bool commitTransaction ( CTransactionRef tx ,
WalletValueMap value_map ,
WalletOrderForm order_form ,
std : : string & reject_reason ) override
{
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
CValidationState state ;
if ( ! m_wallet - > CommitTransaction ( std : : move ( tx ) , std : : move ( value_map ) , std : : move ( order_form ) , state ) ) {
reject_reason = state . GetRejectReason ( ) ;
return false ;
}
return true ;
2017-04-17 18:56:44 -04:00
}
2019-02-21 15:26:29 +00:00
bool transactionCanBeAbandoned ( const uint256 & txid ) override { return m_wallet - > TransactionCanBeAbandoned ( txid ) ; }
2017-04-17 18:56:44 -04:00
bool abandonTransaction ( const uint256 & txid ) override
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
return m_wallet - > AbandonTransaction ( * locked_chain , txid ) ;
2017-04-17 18:56:44 -04:00
}
bool transactionCanBeBumped ( const uint256 & txid ) override
{
2019-02-21 15:26:29 +00:00
return feebumper : : TransactionCanBeBumped ( m_wallet . get ( ) , txid ) ;
2017-04-17 18:56:44 -04:00
}
bool createBumpTransaction ( const uint256 & txid ,
const CCoinControl & coin_control ,
CAmount total_fee ,
std : : vector < std : : string > & errors ,
CAmount & old_fee ,
CAmount & new_fee ,
CMutableTransaction & mtx ) override
{
2019-03-06 16:30:00 -05:00
if ( total_fee > 0 ) {
return feebumper : : CreateTotalBumpTransaction ( m_wallet . get ( ) , txid , coin_control , total_fee , errors , old_fee , new_fee , mtx ) = =
feebumper : : Result : : OK ;
} else {
return feebumper : : CreateRateBumpTransaction ( m_wallet . get ( ) , txid , coin_control , errors , old_fee , new_fee , mtx ) = =
feebumper : : Result : : OK ;
}
2017-04-17 18:56:44 -04:00
}
2019-02-21 15:26:29 +00:00
bool signBumpTransaction ( CMutableTransaction & mtx ) override { return feebumper : : SignTransaction ( m_wallet . get ( ) , mtx ) ; }
2017-04-17 18:56:44 -04:00
bool commitBumpTransaction ( const uint256 & txid ,
CMutableTransaction & & mtx ,
std : : vector < std : : string > & errors ,
uint256 & bumped_txid ) override
{
2019-02-21 15:26:29 +00:00
return feebumper : : CommitTransaction ( m_wallet . get ( ) , txid , std : : move ( mtx ) , errors , bumped_txid ) = =
2017-04-17 18:56:44 -04:00
feebumper : : Result : : OK ;
}
2017-04-18 16:42:30 -04:00
CTransactionRef getTx ( const uint256 & txid ) override
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
auto mi = m_wallet - > mapWallet . find ( txid ) ;
if ( mi ! = m_wallet - > mapWallet . end ( ) ) {
2017-04-18 16:42:30 -04:00
return mi - > second . tx ;
}
return { } ;
}
WalletTx getWalletTx ( const uint256 & txid ) override
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
auto mi = m_wallet - > mapWallet . find ( txid ) ;
if ( mi ! = m_wallet - > mapWallet . end ( ) ) {
return MakeWalletTx ( * locked_chain , * m_wallet , mi - > second ) ;
2017-04-18 16:42:30 -04:00
}
return { } ;
}
std : : vector < WalletTx > getWalletTxs ( ) override
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
2017-04-18 16:42:30 -04:00
std : : vector < WalletTx > result ;
2019-02-21 15:26:29 +00:00
result . reserve ( m_wallet - > mapWallet . size ( ) ) ;
for ( const auto & entry : m_wallet - > mapWallet ) {
result . emplace_back ( MakeWalletTx ( * locked_chain , * m_wallet , entry . second ) ) ;
2017-04-18 16:42:30 -04:00
}
return result ;
}
bool tryGetTxStatus ( const uint256 & txid ,
2018-04-07 03:42:02 -04:00
interfaces : : WalletTxStatus & tx_status ,
2018-10-23 22:02:20 +03:00
int & num_blocks ,
int64_t & block_time ) override
2017-04-18 16:42:30 -04:00
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( true /* try_lock */ ) ;
2017-04-18 16:42:30 -04:00
if ( ! locked_chain ) {
return false ;
}
2019-02-21 15:26:29 +00:00
TRY_LOCK ( m_wallet - > cs_wallet , locked_wallet ) ;
2017-04-18 16:42:30 -04:00
if ( ! locked_wallet ) {
return false ;
}
2019-02-21 15:26:29 +00:00
auto mi = m_wallet - > mapWallet . find ( txid ) ;
if ( mi = = m_wallet - > mapWallet . end ( ) ) {
2017-04-18 16:42:30 -04:00
return false ;
}
2019-01-07 22:35:47 -08:00
if ( Optional < int > height = locked_chain - > getHeight ( ) ) {
num_blocks = * height ;
block_time = locked_chain - > getBlockTime ( * height ) ;
} else {
num_blocks = - 1 ;
block_time = - 1 ;
}
2017-07-31 15:30:21 -04:00
tx_status = MakeWalletTxStatus ( * locked_chain , mi - > second ) ;
2017-04-18 16:42:30 -04:00
return true ;
}
WalletTx getWalletTxDetails ( const uint256 & txid ,
WalletTxStatus & tx_status ,
WalletOrderForm & order_form ,
bool & in_mempool ,
2018-10-23 17:36:46 +03:00
int & num_blocks ) override
2017-04-18 16:42:30 -04:00
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
auto mi = m_wallet - > mapWallet . find ( txid ) ;
if ( mi ! = m_wallet - > mapWallet . end ( ) ) {
2019-01-31 10:46:23 -08:00
num_blocks = locked_chain - > getHeight ( ) . get_value_or ( - 1 ) ;
2017-04-18 16:42:30 -04:00
in_mempool = mi - > second . InMempool ( ) ;
order_form = mi - > second . vOrderForm ;
2017-07-31 15:30:21 -04:00
tx_status = MakeWalletTxStatus ( * locked_chain , mi - > second ) ;
2019-02-21 15:26:29 +00:00
return MakeWalletTx ( * locked_chain , * m_wallet , mi - > second ) ;
2017-04-18 16:42:30 -04:00
}
return { } ;
}
2017-04-17 18:56:44 -04:00
WalletBalances getBalances ( ) override
{
2019-03-11 16:12:58 -04:00
const auto bal = m_wallet - > GetBalance ( ) ;
2017-04-17 18:56:44 -04:00
WalletBalances result ;
2019-03-11 16:12:58 -04:00
result . balance = bal . m_mine_trusted ;
result . unconfirmed_balance = bal . m_mine_untrusted_pending ;
result . immature_balance = bal . m_mine_immature ;
2019-02-21 15:26:29 +00:00
result . have_watch_only = m_wallet - > HaveWatchOnly ( ) ;
2017-04-17 18:56:44 -04:00
if ( result . have_watch_only ) {
2019-03-11 16:12:58 -04:00
result . watch_only_balance = bal . m_watchonly_trusted ;
result . unconfirmed_watch_only_balance = bal . m_watchonly_untrusted_pending ;
result . immature_watch_only_balance = bal . m_watchonly_immature ;
2017-04-17 18:56:44 -04:00
}
return result ;
}
bool tryGetBalances ( WalletBalances & balances , int & num_blocks ) override
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( true /* try_lock */ ) ;
2017-04-17 18:56:44 -04:00
if ( ! locked_chain ) return false ;
2019-02-21 15:26:29 +00:00
TRY_LOCK ( m_wallet - > cs_wallet , locked_wallet ) ;
2017-04-17 18:56:44 -04:00
if ( ! locked_wallet ) {
return false ;
}
balances = getBalances ( ) ;
2019-01-31 10:46:23 -08:00
num_blocks = locked_chain - > getHeight ( ) . get_value_or ( - 1 ) ;
2017-04-17 18:56:44 -04:00
return true ;
}
2020-10-28 01:43:49 +00:00
CAmountMap getBalance ( ) override { return m_wallet - > GetBalance ( ) . m_mine_trusted ; }
2019-03-19 20:26:39 +00:00
CAmountMap getAvailableBalance ( const CCoinControl & coin_control ) override
2017-04-17 18:56:44 -04:00
{
2019-02-21 15:26:29 +00:00
return m_wallet - > GetAvailableBalance ( & coin_control ) ;
2017-04-17 18:56:44 -04:00
}
2017-04-18 16:42:30 -04:00
isminetype txinIsMine ( const CTxIn & txin ) override
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
return m_wallet - > IsMine ( txin ) ;
2017-04-18 16:42:30 -04:00
}
isminetype txoutIsMine ( const CTxOut & txout ) override
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
return m_wallet - > IsMine ( txout ) ;
2017-04-18 16:42:30 -04:00
}
2019-03-19 20:26:39 +00:00
CAmountMap getDebit ( const CTxIn & txin , isminefilter filter ) override
2017-04-18 16:42:30 -04:00
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
return m_wallet - > GetDebit ( txin , filter ) ;
2017-04-18 16:42:30 -04:00
}
2019-05-22 08:43:21 -04:00
CAmountMap getCredit ( const CTransaction & tx , const size_t out_index , isminefilter filter ) override
2017-04-18 16:42:30 -04:00
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
2019-05-22 08:43:21 -04:00
return m_wallet - > GetCredit ( tx , out_index , filter ) ;
2017-04-18 16:42:30 -04:00
}
2017-04-17 19:46:08 -04:00
CoinsList listCoins ( ) override
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
2017-04-17 19:46:08 -04:00
CoinsList result ;
2019-02-21 15:26:29 +00:00
for ( const auto & entry : m_wallet - > ListCoins ( * locked_chain ) ) {
2017-04-17 19:46:08 -04:00
auto & group = result [ entry . first ] ;
for ( const auto & coin : entry . second ) {
2017-07-31 15:30:21 -04:00
group . emplace_back ( COutPoint ( coin . tx - > GetHash ( ) , coin . i ) ,
2019-02-21 15:26:29 +00:00
MakeWalletTxOut ( * locked_chain , * m_wallet , * coin . tx , coin . i , coin . nDepth ) ) ;
2017-04-17 19:46:08 -04:00
}
}
return result ;
}
std : : vector < WalletTxOut > getCoins ( const std : : vector < COutPoint > & outputs ) override
{
2019-02-21 15:26:29 +00:00
auto locked_chain = m_wallet - > chain ( ) . lock ( ) ;
LOCK ( m_wallet - > cs_wallet ) ;
2017-04-17 19:46:08 -04:00
std : : vector < WalletTxOut > result ;
result . reserve ( outputs . size ( ) ) ;
for ( const auto & output : outputs ) {
result . emplace_back ( ) ;
2019-02-21 15:26:29 +00:00
auto it = m_wallet - > mapWallet . find ( output . hash ) ;
if ( it ! = m_wallet - > mapWallet . end ( ) ) {
2017-07-31 15:30:21 -04:00
int depth = it - > second . GetDepthInMainChain ( * locked_chain ) ;
2017-04-17 19:46:08 -04:00
if ( depth > = 0 ) {
2019-02-21 15:26:29 +00:00
result . back ( ) = MakeWalletTxOut ( * locked_chain , * m_wallet , it - > second , output . n , depth ) ;
2017-04-17 19:46:08 -04:00
}
}
}
return result ;
}
2019-02-21 15:26:29 +00:00
CAmount getRequiredFee ( unsigned int tx_bytes ) override { return GetRequiredFee ( * m_wallet , tx_bytes ) ; }
2018-04-07 12:12:46 -04:00
CAmount getMinimumFee ( unsigned int tx_bytes ,
const CCoinControl & coin_control ,
int * returned_target ,
FeeReason * reason ) override
{
FeeCalculation fee_calc ;
CAmount result ;
2017-07-28 21:40:29 -04:00
result = GetMinimumFee ( * m_wallet , tx_bytes , coin_control , & fee_calc ) ;
2018-04-07 12:12:46 -04:00
if ( returned_target ) * returned_target = fee_calc . returnedTarget ;
if ( reason ) * reason = fee_calc . reason ;
return result ;
}
2019-02-21 15:26:29 +00:00
unsigned int getConfirmTarget ( ) override { return m_wallet - > m_confirm_target ; }
bool hdEnabled ( ) override { return m_wallet - > IsHDEnabled ( ) ; }
bool canGetAddresses ( ) override { return m_wallet - > CanGetAddresses ( ) ; }
bool IsWalletFlagSet ( uint64_t flag ) override { return m_wallet - > IsWalletFlagSet ( flag ) ; }
OutputType getDefaultAddressType ( ) override { return m_wallet - > m_default_address_type ; }
OutputType getDefaultChangeType ( ) override { return m_wallet - > m_default_change_type ; }
2019-02-20 13:45:16 -05:00
CAmount getDefaultMaxTxFee ( ) override { return m_wallet - > m_default_max_tx_fee ; }
2019-01-17 17:37:46 +00:00
void remove ( ) override
{
2019-02-21 15:26:29 +00:00
RemoveWallet ( m_wallet ) ;
2019-01-17 17:37:46 +00:00
}
2018-06-05 11:17:28 +01:00
std : : unique_ptr < Handler > handleUnload ( UnloadFn fn ) override
{
2019-02-21 15:26:29 +00:00
return MakeHandler ( m_wallet - > NotifyUnload . connect ( fn ) ) ;
2018-06-05 11:17:28 +01:00
}
2017-04-17 15:10:47 -04:00
std : : unique_ptr < Handler > handleShowProgress ( ShowProgressFn fn ) override
{
2019-02-21 15:26:29 +00:00
return MakeHandler ( m_wallet - > ShowProgress . connect ( fn ) ) ;
2017-04-17 15:10:47 -04:00
}
2017-04-17 18:56:44 -04:00
std : : unique_ptr < Handler > handleStatusChanged ( StatusChangedFn fn ) override
{
2019-06-06 23:58:21 +02:00
return MakeHandler ( m_wallet - > NotifyStatusChanged . connect ( [ fn ] ( CWallet * ) { fn ( ) ; } ) ) ;
2017-04-17 18:56:44 -04:00
}
std : : unique_ptr < Handler > handleAddressBookChanged ( AddressBookChangedFn fn ) override
{
2019-02-21 15:26:29 +00:00
return MakeHandler ( m_wallet - > NotifyAddressBookChanged . connect (
2017-04-17 18:56:44 -04:00
[ fn ] ( CWallet * , const CTxDestination & address , const std : : string & label , bool is_mine ,
const std : : string & purpose , ChangeType status ) { fn ( address , label , is_mine , purpose , status ) ; } ) ) ;
}
std : : unique_ptr < Handler > handleTransactionChanged ( TransactionChangedFn fn ) override
{
2019-02-21 15:26:29 +00:00
return MakeHandler ( m_wallet - > NotifyTransactionChanged . connect (
2018-04-10 15:21:41 +02:00
[ fn ] ( CWallet * , const uint256 & txid , ChangeType status ) { fn ( txid , status ) ; } ) ) ;
2017-04-17 18:56:44 -04:00
}
std : : unique_ptr < Handler > handleWatchOnlyChanged ( WatchOnlyChangedFn fn ) override
{
2019-02-21 15:26:29 +00:00
return MakeHandler ( m_wallet - > NotifyWatchonlyChanged . connect ( fn ) ) ;
2017-04-17 18:56:44 -04:00
}
2019-01-18 17:05:32 -05:00
std : : unique_ptr < Handler > handleCanGetAddressesChanged ( CanGetAddressesChangedFn fn ) override
{
2019-02-21 15:26:29 +00:00
return MakeHandler ( m_wallet - > NotifyCanGetAddressesChanged . connect ( fn ) ) ;
2017-04-17 18:56:44 -04:00
}
2017-04-17 15:10:47 -04:00
2019-02-21 15:26:29 +00:00
std : : shared_ptr < CWallet > m_wallet ;
2017-04-17 15:10:47 -04:00
} ;
2017-05-30 15:55:17 -04:00
class WalletClientImpl : public ChainClient
{
public :
WalletClientImpl ( Chain & chain , std : : vector < std : : string > wallet_filenames )
: m_chain ( chain ) , m_wallet_filenames ( std : : move ( wallet_filenames ) )
{
}
2017-07-31 11:46:13 -04:00
void registerRpcs ( ) override { return RegisterWalletRPCCommands ( m_chain , m_rpc_handlers ) ; }
2017-09-28 14:13:29 -04:00
bool verify ( ) override { return VerifyWallets ( m_chain , m_wallet_filenames ) ; }
bool load ( ) override { return LoadWallets ( m_chain , m_wallet_filenames ) ; }
void start ( CScheduler & scheduler ) override { return StartWallets ( scheduler ) ; }
void flush ( ) override { return FlushWallets ( ) ; }
void stop ( ) override { return StopWallets ( ) ; }
~ WalletClientImpl ( ) override { UnloadWallets ( ) ; }
2017-05-30 15:55:17 -04:00
Chain & m_chain ;
std : : vector < std : : string > m_wallet_filenames ;
2017-07-31 11:46:13 -04:00
std : : vector < std : : unique_ptr < Handler > > m_rpc_handlers ;
2017-05-30 15:55:17 -04:00
} ;
2017-04-17 15:10:47 -04:00
} // namespace
2019-01-22 15:09:57 +00:00
std : : unique_ptr < Wallet > MakeWallet ( const std : : shared_ptr < CWallet > & wallet ) { return wallet ? MakeUnique < WalletImpl > ( wallet ) : nullptr ; }
2017-04-17 15:10:47 -04:00
2017-05-30 15:55:17 -04:00
std : : unique_ptr < ChainClient > MakeWalletClient ( Chain & chain , std : : vector < std : : string > wallet_filenames )
{
return MakeUnique < WalletClientImpl > ( chain , std : : move ( wallet_filenames ) ) ;
}
2018-04-07 03:42:02 -04:00
} // namespace interfaces