@ -37,8 +37,12 @@
# include <boost/archive/binary_oarchive.hpp>
# include <boost/archive/binary_iarchive.hpp>
# include <boost/program_options.hpp>
# include <boost/optional.hpp>
# include <boost/serialization/vector.hpp>
# include <boost/serialization/variant.hpp>
# include <boost/serialization/optional.hpp>
# include <boost/serialization/unordered_map.hpp>
# include <boost/functional/hash.hpp>
# include "include_base_utils.h"
# include "common/boost_serialization_helper.h"
@ -129,13 +133,32 @@ private:
}
} ;
typedef std : : vector < std : : pair < uint8_t , uint64_t > > v_hardforks_t ;
struct event_replay_settings
{
boost : : optional < v_hardforks_t > hard_forks ;
event_replay_settings ( ) = default ;
private :
friend class boost : : serialization : : access ;
template < class Archive >
void serialize ( Archive & ar , const unsigned int /*version*/ )
{
ar & hard_forks ;
}
} ;
VARIANT_TAG ( binary_archive , callback_entry , 0xcb ) ;
VARIANT_TAG ( binary_archive , cryptonote : : account_base , 0xcc ) ;
VARIANT_TAG ( binary_archive , serialized_block , 0xcd ) ;
VARIANT_TAG ( binary_archive , serialized_transaction , 0xce ) ;
VARIANT_TAG ( binary_archive , event_visitor_settings , 0xcf ) ;
VARIANT_TAG ( binary_archive , event_replay_settings , 0xda ) ;
typedef boost : : variant < cryptonote : : block , cryptonote : : transaction , std : : vector < cryptonote : : transaction > , cryptonote : : account_base , callback_entry , serialized_block , serialized_transaction , event_visitor_settings > test_event_entry ;
typedef boost : : variant < cryptonote : : block , cryptonote : : transaction , std : : vector < cryptonote : : transaction > , cryptonote : : account_base , callback_entry , serialized_block , serialized_transaction , event_visitor_settings , event_replay_settings > test_event_entry ;
typedef std : : unordered_map < crypto : : hash , const cryptonote : : transaction * > map_hash2tx_t ;
class test_chain_unit_base
@ -173,6 +196,17 @@ public:
crypto : : hash prev_id ;
uint64_t already_generated_coins ;
size_t block_weight ;
private :
friend class boost : : serialization : : access ;
template < class Archive >
void serialize ( Archive & ar , const unsigned int /*version*/ )
{
ar & prev_id ;
ar & already_generated_coins ;
ar & block_weight ;
}
} ;
enum block_fields
@ -189,6 +223,8 @@ public:
bf_hf_version = 1 < < 8
} ;
test_generator ( ) { }
test_generator ( const test_generator & other ) : m_blocks_info ( other . m_blocks_info ) { }
void get_block_chain ( std : : vector < block_info > & blockchain , const crypto : : hash & head , size_t n ) const ;
void get_last_n_block_weights ( std : : vector < size_t > & block_weights , const crypto : : hash & head , size_t n ) const ;
uint64_t get_already_generated_coins ( const crypto : : hash & blk_id ) const ;
@ -198,10 +234,12 @@ public:
uint8_t hf_version = 1 ) ;
bool construct_block ( cryptonote : : block & blk , uint64_t height , const crypto : : hash & prev_id ,
const cryptonote : : account_base & miner_acc , uint64_t timestamp , uint64_t already_generated_coins ,
std : : vector < size_t > & block_weights , const std : : list < cryptonote : : transaction > & tx_list ) ;
std : : vector < size_t > & block_weights , const std : : list < cryptonote : : transaction > & tx_list ,
const boost : : optional < uint8_t > & hf_ver = boost : : none ) ;
bool construct_block ( cryptonote : : block & blk , const cryptonote : : account_base & miner_acc , uint64_t timestamp ) ;
bool construct_block ( cryptonote : : block & blk , const cryptonote : : block & blk_prev , const cryptonote : : account_base & miner_acc ,
const std : : list < cryptonote : : transaction > & tx_list = std : : list < cryptonote : : transaction > ( ) ) ;
const std : : list < cryptonote : : transaction > & tx_list = std : : list < cryptonote : : transaction > ( ) ,
const boost : : optional < uint8_t > & hf_ver = boost : : none ) ;
bool construct_block_manually ( cryptonote : : block & blk , const cryptonote : : block & prev_block ,
const cryptonote : : account_base & miner_acc , int actual_params = bf_none , uint8_t major_ver = 0 ,
@ -214,30 +252,241 @@ public:
private :
std : : unordered_map < crypto : : hash , block_info > m_blocks_info ;
friend class boost : : serialization : : access ;
template < class Archive >
void serialize ( Archive & ar , const unsigned int /*version*/ )
{
ar & m_blocks_info ;
}
} ;
inline cryptonote : : difficulty_type get_test_difficulty ( ) { return 1 ; }
template < typename T >
std : : string dump_keys ( T * buff32 )
{
std : : ostringstream ss ;
char buff [ 10 ] ;
ss < < " [ " ;
for ( int i = 0 ; i < 32 ; i + + )
{
snprintf ( buff , 10 , " 0x%02x " , ( ( uint8_t ) buff32 [ i ] & 0xff ) ) ;
ss < < buff ;
if ( i < 31 )
ss < < " , " ;
}
ss < < " ] " ;
return ss . str ( ) ;
}
struct output_index {
const cryptonote : : txout_target_v out ;
uint64_t amount ;
size_t blk_height ; // block height
size_t tx_no ; // index of transaction in block
size_t out_no ; // index of out in transaction
size_t idx ;
uint64_t unlock_time ;
bool is_coin_base ;
bool spent ;
bool rct ;
rct : : key comm ;
const cryptonote : : block * p_blk ;
const cryptonote : : transaction * p_tx ;
output_index ( const cryptonote : : txout_target_v & _out , uint64_t _a , size_t _h , size_t tno , size_t ono , const cryptonote : : block * _pb , const cryptonote : : transaction * _pt )
: out ( _out ) , amount ( _a ) , blk_height ( _h ) , tx_no ( tno ) , out_no ( ono ) , idx ( 0 ) , unlock_time ( 0 ) ,
is_coin_base ( false ) , spent ( false ) , rct ( false ) , p_blk ( _pb ) , p_tx ( _pt )
{
}
output_index ( const output_index & other )
: out ( other . out ) , amount ( other . amount ) , blk_height ( other . blk_height ) , tx_no ( other . tx_no ) , rct ( other . rct ) ,
out_no ( other . out_no ) , idx ( other . idx ) , unlock_time ( other . unlock_time ) , is_coin_base ( other . is_coin_base ) ,
spent ( other . spent ) , comm ( other . comm ) , p_blk ( other . p_blk ) , p_tx ( other . p_tx ) { }
void set_rct ( bool arct ) {
rct = arct ;
if ( rct & & p_tx - > rct_signatures . outPk . size ( ) > out_no )
comm = p_tx - > rct_signatures . outPk [ out_no ] . mask ;
else
comm = rct : : commit ( amount , rct : : identity ( ) ) ;
}
rct : : key commitment ( ) const {
return comm ;
}
const std : : string toString ( ) const {
std : : stringstream ss ;
ss < < " output_index{blk_height= " < < blk_height
< < " tx_no= " < < tx_no
< < " out_no= " < < out_no
< < " amount= " < < amount
< < " idx= " < < idx
< < " unlock_time= " < < unlock_time
< < " spent= " < < spent
< < " is_coin_base= " < < is_coin_base
< < " rct= " < < rct
< < " comm= " < < dump_keys ( comm . bytes )
< < " } " ;
return ss . str ( ) ;
}
output_index & operator = ( const output_index & other )
{
new ( this ) output_index ( other ) ;
return * this ;
}
} ;
typedef std : : tuple < uint64_t , crypto : : public_key , rct : : key > get_outs_entry ;
typedef std : : pair < crypto : : hash , size_t > output_hasher ;
typedef boost : : hash < output_hasher > output_hasher_hasher ;
typedef std : : map < uint64_t , std : : vector < size_t > > map_output_t ;
typedef std : : map < uint64_t , std : : vector < output_index > > map_output_idx_t ;
typedef std : : unordered_map < crypto : : hash , cryptonote : : block > map_block_t ;
typedef std : : unordered_map < output_hasher , output_index , output_hasher_hasher > map_txid_output_t ;
typedef std : : unordered_map < crypto : : public_key , cryptonote : : subaddress_index > subaddresses_t ;
typedef std : : pair < uint64_t , size_t > outloc_t ;
typedef boost : : variant < cryptonote : : account_public_address , cryptonote : : account_keys , cryptonote : : account_base , cryptonote : : tx_destination_entry > var_addr_t ;
typedef struct {
const var_addr_t addr ;
bool is_subaddr ;
uint64_t amount ;
} dest_wrapper_t ;
// Daemon functionality
class block_tracker
{
public :
map_output_idx_t m_outs ;
map_txid_output_t m_map_outs ; // mapping (txid, out) -> output_index
map_block_t m_blocks ;
block_tracker ( ) = default ;
block_tracker ( const block_tracker & bt ) : m_outs ( bt . m_outs ) , m_map_outs ( bt . m_map_outs ) , m_blocks ( bt . m_blocks ) { } ;
map_txid_output_t : : iterator find_out ( const crypto : : hash & txid , size_t out ) ;
map_txid_output_t : : iterator find_out ( const output_hasher & id ) ;
void process ( const std : : vector < cryptonote : : block > & blockchain , const map_hash2tx_t & mtx ) ;
void process ( const std : : vector < const cryptonote : : block * > & blockchain , const map_hash2tx_t & mtx ) ;
void process ( const cryptonote : : block * blk , const cryptonote : : transaction * tx , size_t i ) ;
void global_indices ( const cryptonote : : transaction * tx , std : : vector < uint64_t > & indices ) ;
void get_fake_outs ( size_t num_outs , uint64_t amount , uint64_t global_index , uint64_t cur_height , std : : vector < get_outs_entry > & outs ) ;
std : : string dump_data ( ) ;
void dump_data ( const std : : string & fname ) ;
private :
friend class boost : : serialization : : access ;
template < class Archive >
void serialize ( Archive & ar , const unsigned int /*version*/ )
{
ar & m_outs ;
ar & m_map_outs ;
ar & m_blocks ;
}
} ;
std : : string dump_data ( const cryptonote : : transaction & tx ) ;
cryptonote : : account_public_address get_address ( const var_addr_t & inp ) ;
cryptonote : : account_public_address get_address ( const cryptonote : : account_public_address & inp ) ;
cryptonote : : account_public_address get_address ( const cryptonote : : account_keys & inp ) ;
cryptonote : : account_public_address get_address ( const cryptonote : : account_base & inp ) ;
cryptonote : : account_public_address get_address ( const cryptonote : : tx_destination_entry & inp ) ;
inline cryptonote : : difficulty_type get_test_difficulty ( const boost : : optional < uint8_t > & hf_ver = boost : : none ) { return ! hf_ver | | hf_ver . get ( ) < = 1 ? 1 : 2 ; }
inline uint64_t current_difficulty_window ( const boost : : optional < uint8_t > & hf_ver = boost : : none ) { return ! hf_ver | | hf_ver . get ( ) < = 1 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2 ; }
void fill_nonce ( cryptonote : : block & blk , const cryptonote : : difficulty_type & diffic , uint64_t height ) ;
cryptonote : : tx_destination_entry build_dst ( const var_addr_t & to , bool is_subaddr = false , uint64_t amount = 0 ) ;
std : : vector < cryptonote : : tx_destination_entry > build_dsts ( const var_addr_t & to1 , bool sub1 = false , uint64_t am1 = 0 ) ;
std : : vector < cryptonote : : tx_destination_entry > build_dsts ( std : : initializer_list < dest_wrapper_t > inps ) ;
uint64_t sum_amount ( const std : : vector < cryptonote : : tx_destination_entry > & destinations ) ;
uint64_t sum_amount ( const std : : vector < cryptonote : : tx_source_entry > & sources ) ;
bool construct_miner_tx_manually ( size_t height , uint64_t already_generated_coins ,
const cryptonote : : account_public_address & miner_address , cryptonote : : transaction & tx ,
uint64_t fee , cryptonote : : keypair * p_txkey = 0 ) ;
uint64_t fee , cryptonote : : keypair * p_txkey = nullptr ) ;
bool construct_tx_to_key ( const std : : vector < test_event_entry > & events , cryptonote : : transaction & tx ,
const cryptonote : : block & blk_head , const cryptonote : : account_base & from , const cryptonote : : account_base & to ,
uint64_t amount , uint64_t fee , size_t nmix ) ;
const cryptonote : : block & blk_head , const cryptonote : : account_base & from , const var_addr_t & to , uint64_t amount ,
uint64_t fee , size_t nmix , bool rct = false , rct : : RangeProofType range_proof_type = rct : : RangeProofBorromean , int bp_version = 0 ) ;
bool construct_tx_to_key ( const std : : vector < test_event_entry > & events , cryptonote : : transaction & tx , const cryptonote : : block & blk_head ,
const cryptonote : : account_base & from , std : : vector < cryptonote : : tx_destination_entry > destinations ,
uint64_t fee , size_t nmix , bool rct = false , rct : : RangeProofType range_proof_type = rct : : RangeProofBorromean , int bp_version = 0 ) ;
bool construct_tx_to_key ( cryptonote : : transaction & tx , const cryptonote : : account_base & from , const var_addr_t & to , uint64_t amount ,
std : : vector < cryptonote : : tx_source_entry > & sources ,
uint64_t fee , bool rct = false , rct : : RangeProofType range_proof_type = rct : : RangeProofBorromean , int bp_version = 0 ) ;
bool construct_tx_to_key ( cryptonote : : transaction & tx , const cryptonote : : account_base & from , const std : : vector < cryptonote : : tx_destination_entry > & destinations ,
std : : vector < cryptonote : : tx_source_entry > & sources ,
uint64_t fee , bool rct , rct : : RangeProofType range_proof_type , int bp_version = 0 ) ;
cryptonote : : transaction construct_tx_with_fee ( std : : vector < test_event_entry > & events , const cryptonote : : block & blk_head ,
const cryptonote : : account_base & acc_from , const cryptonote : : account_base & acc_to ,
const cryptonote : : account_base & acc_from , const var_addr_t & to,
uint64_t amount , uint64_t fee ) ;
bool construct_tx_rct ( const cryptonote : : account_keys & sender_account_keys ,
std : : vector < cryptonote : : tx_source_entry > & sources ,
const std : : vector < cryptonote : : tx_destination_entry > & destinations ,
const boost : : optional < cryptonote : : account_public_address > & change_addr ,
std : : vector < uint8_t > extra , cryptonote : : transaction & tx , uint64_t unlock_time ,
bool rct = false , rct : : RangeProofType range_proof_type = rct : : RangeProofBorromean , int bp_version = 0 ) ;
uint64_t num_blocks ( const std : : vector < test_event_entry > & events ) ;
cryptonote : : block get_head_block ( const std : : vector < test_event_entry > & events ) ;
void get_confirmed_txs ( const std : : vector < cryptonote : : block > & blockchain , const map_hash2tx_t & mtx , map_hash2tx_t & confirmed_txs ) ;
bool trim_block_chain ( std : : vector < cryptonote : : block > & blockchain , const crypto : : hash & tail ) ;
bool trim_block_chain ( std : : vector < const cryptonote : : block * > & blockchain , const crypto : : hash & tail ) ;
bool find_block_chain ( const std : : vector < test_event_entry > & events , std : : vector < cryptonote : : block > & blockchain , map_hash2tx_t & mtx , const crypto : : hash & head ) ;
bool find_block_chain ( const std : : vector < test_event_entry > & events , std : : vector < const cryptonote : : block * > & blockchain , map_hash2tx_t & mtx , const crypto : : hash & head ) ;
void fill_tx_destinations ( const var_addr_t & from , const cryptonote : : account_public_address & to ,
uint64_t amount , uint64_t fee ,
const std : : vector < cryptonote : : tx_source_entry > & sources ,
std : : vector < cryptonote : : tx_destination_entry > & destinations , bool always_change = false ) ;
void fill_tx_destinations ( const var_addr_t & from , const std : : vector < cryptonote : : tx_destination_entry > & dests ,
uint64_t fee ,
const std : : vector < cryptonote : : tx_source_entry > & sources ,
std : : vector < cryptonote : : tx_destination_entry > & destinations ,
bool always_change ) ;
void fill_tx_destinations ( const var_addr_t & from , const cryptonote : : account_public_address & to ,
uint64_t amount , uint64_t fee ,
const std : : vector < cryptonote : : tx_source_entry > & sources ,
std : : vector < cryptonote : : tx_destination_entry > & destinations ,
std : : vector < cryptonote : : tx_destination_entry > & destinations_pure ,
bool always_change = false ) ;
void fill_tx_sources_and_destinations ( const std : : vector < test_event_entry > & events , const cryptonote : : block & blk_head ,
const cryptonote : : account_base & from , const cryptonote : : account_public_address & to ,
uint64_t amount , uint64_t fee , size_t nmix ,
std : : vector < cryptonote : : tx_source_entry > & sources ,
std : : vector < cryptonote : : tx_destination_entry > & destinations ) ;
void fill_tx_sources_and_destinations ( const std : : vector < test_event_entry > & events , const cryptonote : : block & blk_head ,
const cryptonote : : account_base & from , const cryptonote : : account_base & to ,
uint64_t amount , uint64_t fee , size_t nmix ,
std : : vector < cryptonote : : tx_source_entry > & sources ,
std : : vector < cryptonote : : tx_destination_entry > & destinations ) ;
uint64_t get_balance ( const cryptonote : : account_base & addr , const std : : vector < cryptonote : : block > & blockchain , const map_hash2tx_t & mtx ) ;
bool extract_hard_forks ( const std : : vector < test_event_entry > & events , v_hardforks_t & hard_forks ) ;
//--------------------------------------------------------------------------
template < class t_test_class >
auto do_check_tx_verification_context ( const cryptonote : : tx_verification_context & tvc , bool tx_added , size_t event_index , const cryptonote : : transaction & tx , t_test_class & validator , int )
@ -338,6 +587,12 @@ public:
m_ev_index = ev_index ;
}
bool operator ( ) ( const event_replay_settings & settings )
{
log_event ( " event_replay_settings " ) ;
return true ;
}
bool operator ( ) ( const event_visitor_settings & settings )
{
log_event ( " event_visitor_settings " ) ;
@ -460,13 +715,21 @@ private:
//--------------------------------------------------------------------------
template < class t_test_class >
inline bool replay_events_through_core ( cryptonote : : core & cr , const std : : vector < test_event_entry > & events , t_test_class & validator )
{
return replay_events_through_core_plain ( cr , events , validator , true ) ;
}
//--------------------------------------------------------------------------
template < class t_test_class >
inline bool replay_events_through_core_plain ( cryptonote : : core & cr , const std : : vector < test_event_entry > & events , t_test_class & validator , bool reinit = true )
{
TRY_ENTRY ( ) ;
//init core here
CHECK_AND_ASSERT_MES ( typeid ( cryptonote : : block ) = = events [ 0 ] . type ( ) , false , " First event must be genesis block creation " ) ;
cr . set_genesis_block ( boost : : get < cryptonote : : block > ( events [ 0 ] ) ) ;
if ( reinit ) {
CHECK_AND_ASSERT_MES ( typeid ( cryptonote : : block ) = = events [ 0 ] . type ( ) , false ,
" First event must be genesis block creation " ) ;
cr . set_genesis_block ( boost : : get < cryptonote : : block > ( events [ 0 ] ) ) ;
}
bool r = true ;
push_core_event_visitor < t_test_class > visitor ( cr , events , validator ) ;
@ -489,10 +752,9 @@ struct get_test_options {
} ;
get_test_options ( ) : hard_forks { std : : make_pair ( ( uint8_t ) 1 , ( uint64_t ) 0 ) , std : : make_pair ( ( uint8_t ) 0 , ( uint64_t ) 0 ) } { }
} ;
//--------------------------------------------------------------------------
template < class t_test_class >
inline bool do_replay_events ( std : : vector < test_event_entry > & events )
inline bool do_replay_events _get_core ( std : : vector < test_event_entry > & events , cryptonote : : core * * core )
{
boost : : program_options : : options_description desc ( " Allowed options " ) ;
cryptonote : : core : : init_options ( desc ) ;
@ -506,12 +768,24 @@ inline bool do_replay_events(std::vector<test_event_entry>& events)
if ( ! r )
return false ;
cryptonote : : cryptonote_protocol_stub pr ; //TODO: stub only for this kind of test, make real validation of relayed objects
cryptonote : : core c ( & pr ) ;
* core = new cryptonote : : core ( nullptr ) ;
auto & c = * * core ;
// FIXME: make sure that vm has arg_testnet_on set to true or false if
// this test needs for it to be so.
get_test_options < t_test_class > gto ;
if ( ! c . init ( vm , & gto . test_options ) )
// Hardforks can be specified in events.
v_hardforks_t hardforks ;
cryptonote : : test_options test_options_tmp { } ;
const cryptonote : : test_options * test_options_ = & gto . test_options ;
if ( extract_hard_forks ( events , hardforks ) ) {
hardforks . push_back ( std : : make_pair ( ( uint8_t ) 0 , ( uint64_t ) 0 ) ) ; // terminator
test_options_tmp . hard_forks = hardforks . data ( ) ;
test_options_ = & test_options_tmp ;
}
if ( ! c . init ( vm , test_options_ ) )
{
MERROR ( " Failed to init core " ) ;
return false ;
@ -529,7 +803,31 @@ inline bool do_replay_events(std::vector<test_event_entry>& events)
t_test_class validator ;
bool ret = replay_events_through_core < t_test_class > ( c , events , validator ) ;
c . deinit ( ) ;
// c.deinit();
return ret ;
}
//--------------------------------------------------------------------------
template < class t_test_class >
inline bool replay_events_through_core_validate ( std : : vector < test_event_entry > & events , cryptonote : : core & c )
{
std : : vector < crypto : : hash > pool_txs ;
if ( ! c . get_pool_transaction_hashes ( pool_txs ) )
{
MERROR ( " Failed to flush txpool " ) ;
return false ;
}
c . get_blockchain_storage ( ) . flush_txes_from_pool ( pool_txs ) ;
t_test_class validator ;
return replay_events_through_core_plain < t_test_class > ( c , events , validator , false ) ;
}
//--------------------------------------------------------------------------
template < class t_test_class >
inline bool do_replay_events ( std : : vector < test_event_entry > & events )
{
cryptonote : : core * core ;
bool ret = do_replay_events_get_core < t_test_class > ( events , & core ) ;
core - > deinit ( ) ;
return ret ;
}
//--------------------------------------------------------------------------
@ -546,6 +844,12 @@ inline bool do_replay_file(const std::string& filename)
}
//--------------------------------------------------------------------------
# define DEFAULT_HARDFORKS(HARDFORKS) do { \
HARDFORKS . push_back ( std : : make_pair ( ( uint8_t ) 1 , ( uint64_t ) 0 ) ) ; \
} while ( 0 )
# define ADD_HARDFORK(HARDFORKS, FORK, HEIGHT) HARDFORKS.push_back(std::make_pair((uint8_t)FORK, (uint64_t)HEIGHT))
# define GENERATE_ACCOUNT(account) \
cryptonote : : account_base account ; \
account . generate ( ) ;
@ -589,6 +893,11 @@ inline bool do_replay_file(const std::string& filename)
generator . construct_block ( BLK_NAME , PREV_BLOCK , MINER_ACC ) ; \
VEC_EVENTS . push_back ( BLK_NAME ) ;
# define MAKE_NEXT_BLOCK_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, HF) \
cryptonote : : block BLK_NAME ; \
generator . construct_block ( BLK_NAME , PREV_BLOCK , MINER_ACC , std : : list < cryptonote : : transaction > ( ) , HF ) ; \
VEC_EVENTS . push_back ( BLK_NAME ) ;
# define MAKE_NEXT_BLOCK_TX1(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, TX1) \
cryptonote : : block BLK_NAME ; \
{ \
@ -598,46 +907,91 @@ inline bool do_replay_file(const std::string& filename)
} \
VEC_EVENTS . push_back ( BLK_NAME ) ;
# define MAKE_NEXT_BLOCK_TX1_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, TX1, HF) \
cryptonote : : block BLK_NAME ; \
{ \
std : : list < cryptonote : : transaction > tx_list ; \
tx_list . push_back ( TX1 ) ; \
generator . construct_block ( BLK_NAME , PREV_BLOCK , MINER_ACC , tx_list , HF ) ; \
} \
VEC_EVENTS . push_back ( BLK_NAME ) ;
# define MAKE_NEXT_BLOCK_TX_LIST(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, TXLIST) \
cryptonote : : block BLK_NAME ; \
generator . construct_block ( BLK_NAME , PREV_BLOCK , MINER_ACC , TXLIST ) ; \
VEC_EVENTS . push_back ( BLK_NAME ) ;
# define REWIND_BLOCKS_N(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, COUNT) \
# define MAKE_NEXT_BLOCK_TX_LIST_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, TXLIST, HF) \
cryptonote : : block BLK_NAME ; \
generator . construct_block ( BLK_NAME , PREV_BLOCK , MINER_ACC , TXLIST , HF ) ; \
VEC_EVENTS . push_back ( BLK_NAME ) ;
# define REWIND_BLOCKS_N_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, COUNT, HF) \
cryptonote : : block BLK_NAME ; \
{ \
cryptonote : : block blk_last = PREV_BLOCK ; \
cryptonote : : block blk_last = PREV_BLOCK ; \
for ( size_t i = 0 ; i < COUNT ; + + i ) \
{ \
MAKE_NEXT_BLOCK ( VEC_EVENTS , blk , blk_last , MINER_ACC ) ; \
MAKE_NEXT_BLOCK _HF ( VEC_EVENTS , blk , blk_last , MINER_ACC , HF ); \
blk_last = blk ; \
} \
BLK_NAME = blk_last ; \
}
# define REWIND_BLOCKS_N(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, COUNT) REWIND_BLOCKS_N_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, COUNT, boost::none)
# define REWIND_BLOCKS(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC) REWIND_BLOCKS_N(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW)
# define REWIND_BLOCKS_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, HF) REWIND_BLOCKS_N_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, HF)
# define MAKE_TX_MIX(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
cryptonote : : transaction TX_NAME ; \
construct_tx_to_key ( VEC_EVENTS , TX_NAME , HEAD , FROM , TO , AMOUNT , TESTS_DEFAULT_FEE , NMIX ) ; \
VEC_EVENTS . push_back ( TX_NAME ) ;
# define MAKE_TX_MIX_RCT(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
cryptonote : : transaction TX_NAME ; \
construct_tx_to_key ( VEC_EVENTS , TX_NAME , HEAD , FROM , TO , AMOUNT , TESTS_DEFAULT_FEE , NMIX , true , rct : : RangeProofPaddedBulletproof ) ; \
VEC_EVENTS . push_back ( TX_NAME ) ;
# define MAKE_TX(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, HEAD) MAKE_TX_MIX(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, 0, HEAD)
# define MAKE_TX_MIX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
{ \
cryptonote : : transaction t ; \
cryptonote : : transaction t ; \
construct_tx_to_key ( VEC_EVENTS , t , HEAD , FROM , TO , AMOUNT , TESTS_DEFAULT_FEE , NMIX ) ; \
SET_NAME . push_back ( t ) ; \
VEC_EVENTS . push_back ( t ) ; \
}
# define MAKE_TX_MIX_LIST_RCT(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
MAKE_TX_MIX_LIST_RCT_EX ( VEC_EVENTS , SET_NAME , FROM , TO , AMOUNT , NMIX , HEAD , rct : : RangeProofPaddedBulletproof , 1 )
# define MAKE_TX_MIX_LIST_RCT_EX(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD, RCT_TYPE, BP_VER) \
{ \
cryptonote : : transaction t ; \
construct_tx_to_key ( VEC_EVENTS , t , HEAD , FROM , TO , AMOUNT , TESTS_DEFAULT_FEE , NMIX , true , RCT_TYPE , BP_VER ) ; \
SET_NAME . push_back ( t ) ; \
VEC_EVENTS . push_back ( t ) ; \
}
# define MAKE_TX_MIX_DEST_LIST_RCT(VEC_EVENTS, SET_NAME, FROM, TO, NMIX, HEAD) \
MAKE_TX_MIX_DEST_LIST_RCT_EX ( VEC_EVENTS , SET_NAME , FROM , TO , NMIX , HEAD , rct : : RangeProofPaddedBulletproof , 1 )
# define MAKE_TX_MIX_DEST_LIST_RCT_EX(VEC_EVENTS, SET_NAME, FROM, TO, NMIX, HEAD, RCT_TYPE, BP_VER) \
{ \
cryptonote : : transaction t ; \
construct_tx_to_key ( VEC_EVENTS , t , HEAD , FROM , TO , TESTS_DEFAULT_FEE , NMIX , true , RCT_TYPE , BP_VER ) ; \
SET_NAME . push_back ( t ) ; \
VEC_EVENTS . push_back ( t ) ; \
}
# define MAKE_TX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, HEAD) MAKE_TX_MIX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, 0, HEAD)
# define MAKE_TX_LIST_START(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, HEAD) \
std : : list < cryptonote : : transaction > SET_NAME ; \
MAKE_TX_LIST ( VEC_EVENTS , SET_NAME , FROM , TO , AMOUNT , HEAD ) ;
# define MAKE_TX_LIST_START_RCT(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
std : : list < cryptonote : : transaction > SET_NAME ; \
MAKE_TX_MIX_LIST_RCT ( VEC_EVENTS , SET_NAME , FROM , TO , AMOUNT , NMIX , HEAD ) ;
# define MAKE_MINER_TX_AND_KEY_MANUALLY(TX, BLK, KEY) \
transaction TX ; \
if ( ! construct_miner_tx_manually ( get_block_height ( BLK ) + 1 , generator . get_already_generated_coins ( BLK ) , \
@ -668,19 +1022,7 @@ inline bool do_replay_file(const std::string& filename)
return 1 ; \
}
# define GENERATE_AND_PLAY(genclass) \
if ( list_tests ) \
std : : cout < < # genclass < < std : : endl ; \
else if ( filter . empty ( ) | | boost : : regex_match ( std : : string ( # genclass ) , match , boost : : regex ( filter ) ) ) \
{ \
std : : vector < test_event_entry > events ; \
+ + tests_count ; \
bool generated = false ; \
try \
{ \
genclass g ; \
generated = g . generate ( events ) ; ; \
} \
# define CATCH_REPLAY(genclass) \
catch ( const std : : exception & ex ) \
{ \
MERROR ( # genclass < < " generation failed: what= " < < ex . what ( ) ) ; \
@ -688,7 +1030,9 @@ inline bool do_replay_file(const std::string& filename)
catch ( . . . ) \
{ \
MERROR ( # genclass < < " generation failed: generic exception " ) ; \
} \
}
# define REPLAY_CORE(genclass) \
if ( generated & & do_replay_events < genclass > ( events ) ) \
{ \
MGINFO_GREEN ( " #TEST# Succeeded " < < # genclass ) ; \
@ -697,7 +1041,54 @@ inline bool do_replay_file(const std::string& filename)
{ \
MERROR ( " #TEST# Failed " < < # genclass ) ; \
failed_tests . push_back ( # genclass ) ; \
}
# define REPLAY_WITH_CORE(genclass, CORE) \
if ( generated & & replay_events_through_core_validate < genclass > ( events , CORE ) ) \
{ \
MGINFO_GREEN ( " #TEST# Succeeded " < < # genclass ) ; \
} \
else \
{ \
MERROR ( " #TEST# Failed " < < # genclass ) ; \
failed_tests . push_back ( # genclass ) ; \
}
# define CATCH_GENERATE_REPLAY(genclass) \
CATCH_REPLAY ( genclass ) ; \
REPLAY_CORE ( genclass ) ;
# define CATCH_GENERATE_REPLAY_CORE(genclass, CORE) \
CATCH_REPLAY ( genclass ) ; \
REPLAY_WITH_CORE ( genclass , CORE ) ;
# define GENERATE_AND_PLAY(genclass) \
if ( list_tests ) \
std : : cout < < # genclass < < std : : endl ; \
else if ( filter . empty ( ) | | boost : : regex_match ( std : : string ( # genclass ) , match , boost : : regex ( filter ) ) ) \
{ \
std : : vector < test_event_entry > events ; \
+ + tests_count ; \
bool generated = false ; \
try \
{ \
genclass g ; \
generated = g . generate ( events ) ; \
} \
CATCH_GENERATE_REPLAY ( genclass ) ; \
}
# define GENERATE_AND_PLAY_INSTANCE(genclass, ins, CORE) \
if ( filter . empty ( ) | | boost : : regex_match ( std : : string ( # genclass ) , match , boost : : regex ( filter ) ) ) \
{ \
std : : vector < test_event_entry > events ; \
+ + tests_count ; \
bool generated = false ; \
try \
{ \
generated = ins . generate ( events ) ; \
} \
CATCH_GENERATE_REPLAY_CORE ( genclass , CORE ) ; \
}
# define CALL_TEST(test_name, function) \