2024-07-11 22:09:55 +02:00
// Copyright (c) 2014-2024 Zano Project
2018-12-27 18:50:45 +03:00
// Copyright (c) 2014-2018 The Louisdor Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
# pragma once
# include "chaingen.h"
2024-07-11 22:09:55 +02:00
# include "currency_protocol/currency_protocol_handler.h"
# include "currency_core/currency_core.h"
# include "p2p/net_node.h"
# include "currency_core/bc_offers_service.h"
# include "rpc/core_rpc_server.h"
2018-12-27 18:50:45 +03:00
2025-05-15 05:39:34 +03:00
template < typename wallet_t >
void set_playtime_test_wallet_options ( std : : shared_ptr < wallet_t > w )
{
w - > set_disable_tor_relay ( true ) ;
w - > set_concise_mode ( true ) ;
w - > set_concise_mode_reorg_max_reorg_blocks ( TESTS_CONCISE_MODE_REORG_MAX_REORG_BLOCK ) ;
w - > set_use_assets_whitelisting ( false ) ;
}
2020-05-27 13:12:28 +03:00
struct wallet_test : virtual public test_chain_unit_enchanced
2018-12-27 18:50:45 +03:00
{
enum { MINER_ACC_IDX = 0 , ALICE_ACC_IDX = 1 , BOB_ACC_IDX = 2 , CAROL_ACC_IDX = 3 , DAN_ACC_IDX = 4 , TOTAL_ACCS_COUNT = 5 } ; // to be used as index for m_accounts
wallet_test ( ) ;
bool need_core_proxy ( ) const { return true ; }
void set_core_proxy ( std : : shared_ptr < tools : : i_core_proxy > p ) { m_core_proxy = p ; }
bool check_balance_via_build_wallets ( currency : : core & c , size_t ev_index , const std : : vector < test_event_entry > & events ) ;
bool check_balance ( currency : : core & c , size_t ev_index , const std : : vector < test_event_entry > & events ) ;
2023-06-03 04:12:01 +02:00
void on_test_constructed ( ) override { on_test_generator_created ( this - > generator ) ; }
2022-11-01 00:11:51 +01:00
static std : : string get_test_account_name_by_id ( size_t acc_id ) ;
2023-08-24 20:32:50 +02:00
template < typename wallet_t >
2024-07-11 22:09:55 +02:00
std : : shared_ptr < wallet_t > init_playtime_test_wallet_t ( const std : : vector < test_event_entry > & events , currency : : core & c , const currency : : account_base & acc , bool true_http_rpc = false ) const
2023-08-24 20:32:50 +02:00
{
2024-08-02 12:31:33 +02:00
# define LOCAL_HOST_CSTR "127.0.0.1"
# define LOCAL_PORT_CSTR "33777"
2023-08-24 20:32:50 +02:00
CHECK_AND_ASSERT_THROW_MES ( events . size ( ) > 0 & & events [ 0 ] . type ( ) = = typeid ( currency : : block ) , " Invalid events queue, can't find genesis block at the beginning " ) ;
2023-08-28 20:50:40 +02:00
crypto : : hash genesis_hash = get_block_hash ( boost : : get < currency : : block > ( events [ 0 ] ) ) ;
2023-08-24 20:32:50 +02:00
2024-07-11 22:09:55 +02:00
if ( true_http_rpc )
{
m_core_proxy = std : : make_shared < tools : : default_http_core_proxy > ( ) ;
m_core_proxy - > set_connectivity ( 100 , 1 ) ;
2024-08-02 12:31:33 +02:00
CHECK_AND_ASSERT_THROW_MES ( m_core_proxy - > set_connection_addr ( LOCAL_HOST_CSTR " : " LOCAL_PORT_CSTR ) , " set_connection_addr failed " ) ;
2024-07-11 22:09:55 +02:00
if ( ! m_core_proxy - > check_connection ( ) )
{
// if there's not http rpc core server yet, create one
boost : : program_options : : options_description desc_options ;
currency : : core_rpc_server : : init_options ( desc_options ) ;
boost : : program_options : : variables_map vm { } ;
2024-08-02 12:31:33 +02:00
const char * const argv [ ] = { " --rpc-bind-ip= " LOCAL_HOST_CSTR , " --rpc-bind-port= " LOCAL_PORT_CSTR } ;
2024-07-11 22:09:55 +02:00
boost : : program_options : : store ( boost : : program_options : : parse_command_line ( sizeof argv / sizeof argv [ 0 ] , argv , desc_options ) , vm ) ;
m_http_rpc_server = std : : make_shared < core_http_rpc_server_details > ( c , vm ) ;
}
m_core_proxy - > set_connectivity ( 30000 , 1 ) ;
2024-07-13 00:31:49 +02:00
CHECK_AND_ASSERT_THROW_MES ( m_core_proxy - > check_connection ( ) , " m_core_proxy: no connection " ) ;
2024-07-11 22:09:55 +02:00
}
2023-08-24 20:32:50 +02:00
std : : shared_ptr < wallet_t > w ( new wallet_t ) ;
w - > set_core_runtime_config ( c . get_blockchain_storage ( ) . get_core_runtime_config ( ) ) ;
w - > assign_account ( acc ) ;
w - > set_genesis ( genesis_hash ) ;
w - > set_core_proxy ( m_core_proxy ) ;
2025-05-15 05:39:34 +03:00
set_playtime_test_wallet_options ( w ) ;
2023-08-24 20:32:50 +02:00
return w ;
2024-08-02 12:31:33 +02:00
# undef LOCAL_HOST_CSTR
# undef LOCAL_PORT_CSTR
2023-08-24 20:32:50 +02:00
}
template < typename wallet_t >
2023-08-28 20:58:26 +02:00
std : : shared_ptr < wallet_t > init_playtime_test_wallet_t ( const std : : vector < test_event_entry > & events , currency : : core & c , size_t account_index ) const
2023-08-24 20:32:50 +02:00
{
CHECK_AND_ASSERT_THROW_MES ( account_index < m_accounts . size ( ) , " Invalid account index " ) ;
return init_playtime_test_wallet_t < wallet_t > ( events , c , m_accounts [ account_index ] ) ;
}
2018-12-27 18:50:45 +03:00
protected :
struct params_check_balance
{
params_check_balance ( size_t account_index = 0 ,
uint64_t total_balance = 0 ,
uint64_t unlocked_balance = std : : numeric_limits < uint64_t > : : max ( ) ,
uint64_t mined_balance = std : : numeric_limits < uint64_t > : : max ( ) ,
uint64_t awaiting_in = std : : numeric_limits < uint64_t > : : max ( ) ,
uint64_t awaiting_out = std : : numeric_limits < uint64_t > : : max ( ) )
: account_index ( account_index ) , total_balance ( total_balance ) , unlocked_balance ( unlocked_balance ) , mined_balance ( mined_balance ) , awaiting_in ( awaiting_in ) , awaiting_out ( awaiting_out ) { }
uint64_t total_balance ;
uint64_t unlocked_balance ;
uint64_t mined_balance ;
uint64_t awaiting_in ;
uint64_t awaiting_out ;
size_t account_index ;
} ;
2024-07-11 22:09:55 +02:00
struct core_http_rpc_server_details
{
currency : : t_currency_protocol_handler < currency : : core > cph ;
nodetool : : node_server < currency : : t_currency_protocol_handler < currency : : core > > p2p ;
bc_services : : bc_offers_service bos ;
currency : : core_rpc_server core_rpc_server ;
core_http_rpc_server_details ( currency : : core & c , const boost : : program_options : : variables_map & vm )
: cph ( c , nullptr )
, p2p ( cph )
, bos ( nullptr )
, core_rpc_server ( c , p2p , bos )
{
bos . set_disabled ( true ) ;
core_rpc_server . set_ignore_connectivity_status ( true ) ;
bool r = core_rpc_server . init ( vm ) ;
CRYPTO_CHECK_AND_THROW_MES ( r , " core_http_rpc_server_details: rpc server init failed " ) ;
r = core_rpc_server . run ( 2 , false ) ;
CRYPTO_CHECK_AND_THROW_MES ( r , " core_http_rpc_server_details: rpc server run failed " ) ;
}
~ core_http_rpc_server_details ( )
{
core_rpc_server . deinit ( ) ;
}
} ;
2018-12-27 18:50:45 +03:00
std : : shared_ptr < tools : : wallet2 > init_playtime_test_wallet ( const std : : vector < test_event_entry > & events , currency : : core & c , size_t account_index ) const ;
std : : shared_ptr < tools : : wallet2 > init_playtime_test_wallet ( const std : : vector < test_event_entry > & events , currency : : core & c , const currency : : account_base & acc ) const ;
2024-07-13 00:31:49 +02:00
std : : shared_ptr < tools : : wallet2 > init_playtime_test_wallet_with_true_http_rpc ( const std : : vector < test_event_entry > & events , currency : : core & c , size_t account_index ) const ;
2018-12-27 18:50:45 +03:00
mutable std : : vector < currency : : account_base > m_accounts ;
mutable test_generator generator ;
2024-07-11 22:09:55 +02:00
mutable std : : shared_ptr < tools : : i_core_proxy > m_core_proxy ;
mutable std : : shared_ptr < core_http_rpc_server_details > m_http_rpc_server ; // "True" RPC via http on localhost
2018-12-27 18:50:45 +03:00
} ;
2019-11-07 13:39:46 +03:00
2023-06-13 00:16:46 +02:00
2023-06-13 23:06:55 +02:00
inline const tools : : wallet_public : : asset_balance_entry get_native_balance_entry ( const std : : list < tools : : wallet_public : : asset_balance_entry > & balances )
2023-06-13 00:16:46 +02:00
{
for ( const auto & b : balances )
{
if ( b . asset_info . asset_id = = currency : : native_coin_asset_id )
return b ;
}
return tools : : wallet_public : : asset_balance_entry ( ) ;
}
2019-11-07 13:39:46 +03:00
// wallet callback helper to check balance in wallet callbacks
// see escrow_balance test for usage example
struct wallet_callback_balance_checker : public tools : : i_wallet2_callback
{
wallet_callback_balance_checker ( const std : : string & label ) : m_label ( label ) , m_result ( true ) , m_called ( false ) , m_balance ( UINT64_MAX ) , m_unlocked_balance ( UINT64_MAX ) , m_total_mined ( UINT64_MAX ) { }
void expect_balance ( uint64_t balance = UINT64_MAX , uint64_t unlocked_balance = UINT64_MAX , uint64_t total_mined = UINT64_MAX )
{
m_balance = balance ;
m_unlocked_balance = unlocked_balance ;
m_total_mined = total_mined ;
m_called = false ;
}
2023-06-13 00:16:46 +02:00
virtual void on_transfer2 ( const tools : : wallet_public : : wallet_transfer_info & wti , const std : : list < tools : : wallet_public : : asset_balance_entry > & balances , uint64_t total_mined ) override
2019-11-07 13:39:46 +03:00
{
2023-06-13 00:16:46 +02:00
tools : : wallet_public : : asset_balance_entry native_balance = get_native_balance_entry ( balances ) ;
uint64_t balance = native_balance . total ;
uint64_t unlocked_balance = native_balance . unlocked ;
2019-11-07 13:39:46 +03:00
m_called = true ;
m_result = false ;
CHECK_AND_ASSERT_MES ( m_balance = = UINT64_MAX | | balance = = m_balance , ( void ) ( 0 ) , m_label < < " balance is incorrect: " < < currency : : print_money_brief ( balance ) < < " , expected: " < < currency : : print_money_brief ( m_balance ) ) ;
CHECK_AND_ASSERT_MES ( m_unlocked_balance = = UINT64_MAX | | unlocked_balance = = m_unlocked_balance , ( void ) ( 0 ) , m_label < < " unlocked balance is incorrect: " < < currency : : print_money_brief ( unlocked_balance ) < < " , expected: " < < currency : : print_money_brief ( m_unlocked_balance ) ) ;
CHECK_AND_ASSERT_MES ( m_total_mined = = UINT64_MAX | | total_mined = = m_total_mined , ( void ) ( 0 ) , m_label < < " total mined is incorrect: " < < currency : : print_money_brief ( total_mined ) < < " , expected: " < < currency : : print_money_brief ( m_total_mined ) ) ;
m_result = true ;
}
bool check ( )
{
bool result = m_result ;
m_result = false ; // clear result to avoid errorneous successive calls to check() without calling except_balance()
return result ;
}
bool called ( )
{
return m_called ;
}
bool m_result ;
bool m_called ;
std : : string m_label ;
uint64_t m_balance ;
uint64_t m_unlocked_balance ;
uint64_t m_total_mined ;
} ;
2020-04-28 15:51:41 +03:00
struct wlt_lambda_on_transfer2_wrapper : public tools : : i_wallet2_callback
{
2023-06-13 00:16:46 +02:00
typedef std : : function < bool ( const tools : : wallet_public : : wallet_transfer_info & , const std : : list < tools : : wallet_public : : asset_balance_entry > & , uint64_t ) > Func ;
2020-04-28 15:51:41 +03:00
wlt_lambda_on_transfer2_wrapper ( Func callback ) : m_result ( false ) , m_callback ( callback ) { }
2023-06-13 00:16:46 +02:00
virtual void on_transfer2 ( const tools : : wallet_public : : wallet_transfer_info & wti , const std : : list < tools : : wallet_public : : asset_balance_entry > & balances , uint64_t total_mined ) override
2020-04-28 15:51:41 +03:00
{
2023-06-13 00:16:46 +02:00
m_result = m_callback ( wti , balances , total_mined ) ;
2020-04-28 15:51:41 +03:00
}
bool m_result ;
Func m_callback ;
} ;
2023-08-24 17:56:59 +02:00
class debug_wallet2 : public tools : : wallet2
{
public :
epee : : misc_utils : : events_dispatcher & get_debug_events_dispatcher ( )
{
return this - > m_debug_events_dispatcher ;
}
} ;