@ -270,7 +270,8 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, const bool fakechain
m_db = db ;
if ( testnet ) {
m_testnet = testnet ;
if ( m_testnet ) {
m_hardfork = new HardFork ( * db , 1 , testnet_hard_fork_version_1_till ) ;
for ( size_t n = 0 ; n < sizeof ( testnet_hard_forks ) / sizeof ( testnet_hard_forks [ 0 ] ) ; + + n )
m_hardfork - > add_fork ( testnet_hard_forks [ n ] . version , testnet_hard_forks [ n ] . height , testnet_hard_forks [ n ] . threshold , testnet_hard_forks [ n ] . time ) ;
@ -292,7 +293,7 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, const bool fakechain
LOG_PRINT_L0 ( " Blockchain not loaded, generating genesis block. " ) ;
block bl = boost : : value_initialized < block > ( ) ;
block_verification_context bvc = boost : : value_initialized < block_verification_context > ( ) ;
if ( testnet)
if ( m_ testnet)
{
generate_genesis_block ( bl , config : : testnet : : GENESIS_TX , config : : testnet : : GENESIS_NONCE ) ;
}
@ -330,45 +331,8 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, const bool fakechain
m_async_pool . create_thread ( boost : : bind ( & boost : : asio : : io_service : : run , & m_async_service ) ) ;
# if defined(PER_BLOCK_CHECKPOINT)
if ( ! fakechain & & m_fast_sync & & get_blocks_dat_start ( testnet ) ! = nullptr )
{
if ( get_blocks_dat_size ( testnet ) > 4 )
{
const unsigned char * p = get_blocks_dat_start ( testnet ) ;
const uint32_t nblocks = * p | ( ( * ( p + 1 ) ) < < 8 ) | ( ( * ( p + 2 ) ) < < 16 ) | ( ( * ( p + 3 ) ) < < 24 ) ;
const size_t size_needed = 4 + nblocks * sizeof ( crypto : : hash ) ;
if ( nblocks > 0 & & nblocks > m_db - > height ( ) & & get_blocks_dat_size ( testnet ) > = size_needed )
{
LOG_PRINT_L0 ( " Loading precomputed blocks: " < < nblocks ) ;
p + = sizeof ( uint32_t ) ;
for ( uint32_t i = 0 ; i < nblocks ; i + + )
{
crypto : : hash hash ;
memcpy ( hash . data , p , sizeof ( hash . data ) ) ;
p + = sizeof ( hash . data ) ;
m_blocks_hash_check . push_back ( hash ) ;
}
// FIXME: clear tx_pool because the process might have been
// terminated and caused it to store txs kept by blocks.
// The core will not call check_tx_inputs(..) for these
// transactions in this case. Consequently, the sanity check
// for tx hashes will fail in handle_block_to_main_chain(..)
std : : list < transaction > txs ;
m_tx_pool . get_transactions ( txs ) ;
size_t blob_size ;
uint64_t fee ;
bool relayed ;
transaction pool_tx ;
for ( const transaction & tx : txs )
{
crypto : : hash tx_hash = get_transaction_hash ( tx ) ;
m_tx_pool . take_tx ( tx_hash , pool_tx , blob_size , fee , relayed ) ;
}
}
}
}
if ( ! fakechain )
load_compiled_in_block_hashes ( ) ;
# endif
LOG_PRINT_GREEN ( " Blockchain initialized. last block: " < < m_db - > height ( ) - 1 < < " , " < < epee : : misc_utils : : get_time_interval_string ( timestamp_diff ) < < " time ago, current difficulty: " < < get_difficulty_for_next_block ( ) , LOG_LEVEL_0 ) ;
@ -652,10 +616,10 @@ void Blockchain::get_all_known_block_ids(std::list<crypto::hash> &main, std::lis
main . push_back ( a ) ;
}
BOOST_FOREACH ( const blocks_ext_by_hash : : value_type & v , m_alternative_chains )
for ( const blocks_ext_by_hash : : value_type & v : m_alternative_chains )
alt . push_back ( v . first ) ;
BOOST_FOREACH ( const blocks_ext_by_hash : : value_type & v , m_invalid_blocks )
for ( const blocks_ext_by_hash : : value_type & v : m_invalid_blocks )
invalid . push_back ( v . first ) ;
}
//------------------------------------------------------------------
@ -836,7 +800,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::
}
//removing alt_chain entries from alternative chain
BOOST_FOREACH ( auto ch_ent , alt_chain )
for ( auto ch_ent : alt_chain )
{
m_alternative_chains . erase ( ch_ent ) ;
}
@ -948,7 +912,7 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl
LOG_PRINT_L3 ( " Blockchain:: " < < __func__ ) ;
//validate reward
uint64_t money_in_use = 0 ;
BOOST_FOREACH ( auto & o , b . miner_tx . vout )
for ( auto & o : b . miner_tx . vout )
money_in_use + = o . amount ;
partial_block_reward = false ;
@ -1055,7 +1019,7 @@ bool Blockchain::create_block_template(block& b, const account_public_address& m
size_t real_txs_size = 0 ;
uint64_t real_fee = 0 ;
CRITICAL_REGION_BEGIN ( m_tx_pool . m_transactions_lock ) ;
BOOST_FOREACH ( crypto : : hash & cur_hash , b . tx_hashes )
for ( crypto : : hash & cur_hash : b . tx_hashes )
{
auto cur_res = m_tx_pool . m_transactions . find ( cur_hash ) ;
if ( cur_res = = m_tx_pool . m_transactions . end ( ) )
@ -1409,26 +1373,40 @@ bool Blockchain::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NO
std : : list < block > blocks ;
get_blocks ( arg . blocks , blocks , rsp . missed_ids ) ;
BOOST_FOREACH ( const auto & bl , blocks )
for ( const auto & bl : blocks )
{
std : : list < crypto : : hash > missed_tx_id ;
std : : list < crypto : : hash > missed_tx_id s ;
std : : list < transaction > txs ;
get_transactions ( bl . tx_hashes , txs , rsp . missed_ids ) ;
CHECK_AND_ASSERT_MES ( ! missed_tx_id . size ( ) , false , " Internal error: has missed missed_tx_id.size()= " < < missed_tx_id . size ( )
< < std : : endl < < " for block id = " < < get_block_hash ( bl ) ) ;
get_transactions ( bl . tx_hashes , txs , missed_tx_ids ) ;
if ( missed_tx_ids . size ( ) ! = 0 )
{
LOG_ERROR ( " Error retrieving blocks, missed " < < missed_tx_ids . size ( )
< < " transactions for block with hash: " < < get_block_hash ( bl )
< < std : : endl
) ;
rsp . missed_ids . push_back ( get_block_hash ( bl ) ) ;
// append missed transaction hashes to response missed_ids field,
// as done below if any standalone transactions were requested
// and missed.
rsp . missed_ids . splice ( rsp . missed_ids . end ( ) , missed_tx_ids ) ;
return false ;
}
rsp . blocks . push_back ( block_complete_entry ( ) ) ;
block_complete_entry & e = rsp . blocks . back ( ) ;
//pack block
e . block = t_serializable_object_to_blob ( bl ) ;
//pack transactions
BOOST_FOREACH ( transaction & tx , txs )
for ( transaction & tx : txs )
e . txs . push_back ( t_serializable_object_to_blob ( tx ) ) ;
}
//get another transactions, if need
std : : list < transaction > txs ;
get_transactions ( arg . txs , txs , rsp . missed_ids ) ;
//pack aside transactions
BOOST_FOREACH ( const auto & tx , txs )
for ( const auto & tx : txs )
rsp . txs . push_back ( t_serializable_object_to_blob ( tx ) ) ;
return true ;
@ -1439,7 +1417,7 @@ bool Blockchain::get_alternative_blocks(std::list<block>& blocks) const
LOG_PRINT_L3 ( " Blockchain:: " < < __func__ ) ;
CRITICAL_REGION_LOCAL ( m_blockchain_lock ) ;
BOOST_FOREACH ( const auto & alt_bl , m_alternative_chains )
for ( const auto & alt_bl : m_alternative_chains )
{
blocks . push_back ( alt_bl . second . bl ) ;
}
@ -1988,7 +1966,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx)
// from hard fork 2, we forbid dust and compound outputs
if ( m_hardfork - > get_current_version ( ) > = 2 ) {
BOOST_FOREACH ( auto & o , tx . vout ) {
for ( auto & o : tx . vout ) {
if ( ! is_valid_decomposed_amount ( o . amount ) ) {
return false ;
}
@ -2001,7 +1979,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx)
bool Blockchain : : have_tx_keyimges_as_spent ( const transaction & tx ) const
{
LOG_PRINT_L3 ( " Blockchain:: " < < __func__ ) ;
BOOST_FOREACH ( const txin_v & in , tx . vin )
for ( const txin_v & in : tx . vin )
{
CHECKED_GET_SPECIFIC_VARIANT ( in , const txin_to_key , in_to_key , true ) ;
if ( have_tx_keyimg_as_spent ( in_to_key . k_image ) )
@ -3249,6 +3227,49 @@ bool Blockchain::get_hard_fork_voting_info(uint8_t version, uint32_t &window, ui
return m_hardfork - > get_voting_info ( version , window , votes , threshold , earliest_height , voting ) ;
}
void Blockchain : : load_compiled_in_block_hashes ( )
{
if ( m_fast_sync & & get_blocks_dat_start ( m_testnet ) ! = nullptr )
{
if ( get_blocks_dat_size ( m_testnet ) > 4 )
{
const unsigned char * p = get_blocks_dat_start ( m_testnet ) ;
const uint32_t nblocks = * p | ( ( * ( p + 1 ) ) < < 8 ) | ( ( * ( p + 2 ) ) < < 16 ) | ( ( * ( p + 3 ) ) < < 24 ) ;
const size_t size_needed = 4 + nblocks * sizeof ( crypto : : hash ) ;
if ( nblocks > 0 & & nblocks > m_db - > height ( ) & & get_blocks_dat_size ( m_testnet ) > = size_needed )
{
LOG_PRINT_L0 ( " Loading precomputed blocks: " < < nblocks ) ;
p + = sizeof ( uint32_t ) ;
for ( uint32_t i = 0 ; i < nblocks ; i + + )
{
crypto : : hash hash ;
memcpy ( hash . data , p , sizeof ( hash . data ) ) ;
p + = sizeof ( hash . data ) ;
m_blocks_hash_check . push_back ( hash ) ;
}
// FIXME: clear tx_pool because the process might have been
// terminated and caused it to store txs kept by blocks.
// The core will not call check_tx_inputs(..) for these
// transactions in this case. Consequently, the sanity check
// for tx hashes will fail in handle_block_to_main_chain(..)
std : : list < transaction > txs ;
m_tx_pool . get_transactions ( txs ) ;
size_t blob_size ;
uint64_t fee ;
bool relayed ;
transaction pool_tx ;
for ( const transaction & tx : txs )
{
crypto : : hash tx_hash = get_transaction_hash ( tx ) ;
m_tx_pool . take_tx ( tx_hash , pool_tx , blob_size , fee , relayed ) ;
}
}
}
}
}
bool Blockchain : : for_all_key_images ( std : : function < bool ( const crypto : : key_image & ) > f ) const
{
return m_db - > for_all_key_images ( f ) ;