Blockchain issues and UI improvements
This commit is contained in:
parent
7c23c01d41
commit
baaa348427
23 changed files with 454 additions and 81 deletions
|
@ -7,12 +7,6 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
|||
set(CMAKE_CONFIGURATION_TYPES "Debug;Release")
|
||||
enable_testing()
|
||||
|
||||
function(set_static_flags)
|
||||
if (NOT APPLE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
|
||||
endif()
|
||||
endfunction(set_static_flags)
|
||||
|
||||
include_directories(src contrib/epee/include external "${CMAKE_BINARY_DIR}/version")
|
||||
if(APPLE)
|
||||
include_directories(SYSTEM /usr/include/malloc)
|
||||
|
@ -76,8 +70,8 @@ else()
|
|||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEBUG_FLAGS}")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${RELEASE_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${RELEASE_FLAGS}")
|
||||
if(STATIC)
|
||||
set_static_flags()
|
||||
if(STATIC AND NOT APPLE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -85,7 +79,7 @@ if(STATIC)
|
|||
set(Boost_USE_STATIC_LIBS ON)
|
||||
set(Boost_USE_STATIC_RUNTIME ON)
|
||||
endif()
|
||||
find_package(Boost 1.53 REQUIRED COMPONENTS system filesystem thread date_time chrono regex serialization atomic program_options)
|
||||
find_package(Boost 1.53 REQUIRED COMPONENTS system filesystem thread date_time chrono regex serialization program_options)
|
||||
if((${Boost_MAJOR_VERSION} EQUAL 1) AND (${Boost_MINOR_VERSION} EQUAL 54))
|
||||
message(SEND_ERROR "Boost version 1.54 is unsupported, more details are available here http://goo.gl/RrCFmA")
|
||||
endif()
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
Release notes 0.8.8
|
||||
|
||||
- Fixed a bug with checkpoints behavior
|
||||
- UI improvements for daemon
|
||||
- Various updates from our forks
|
||||
|
||||
Release notes 0.8.7
|
||||
|
||||
- OSX support
|
||||
|
|
|
@ -372,7 +372,7 @@ bool blockchain_storage::rollback_blockchain_switching(std::list<block>& origina
|
|||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::iterator>& alt_chain)
|
||||
bool blockchain_storage::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::iterator>& alt_chain, bool discard_disconnected_chain)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
CHECK_AND_ASSERT_MES(alt_chain.size(), false, "switch_to_alternative_blockchain: empty chain passed");
|
||||
|
@ -414,16 +414,19 @@ bool blockchain_storage::switch_to_alternative_blockchain(std::list<blocks_ext_b
|
|||
}
|
||||
}
|
||||
|
||||
//pushing old chain as alternative chain
|
||||
BOOST_FOREACH(auto& old_ch_ent, disconnected_chain)
|
||||
if(!discard_disconnected_chain)
|
||||
{
|
||||
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
||||
bool r = handle_alternative_block(old_ch_ent, get_block_hash(old_ch_ent), bvc);
|
||||
if(!r)
|
||||
//pushing old chain as alternative chain
|
||||
BOOST_FOREACH(auto& old_ch_ent, disconnected_chain)
|
||||
{
|
||||
LOG_ERROR("Failed to push ex-main chain blocks to alternative chain ");
|
||||
rollback_blockchain_switching(disconnected_chain, split_height);
|
||||
return false;
|
||||
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
||||
bool r = handle_alternative_block(old_ch_ent, get_block_hash(old_ch_ent), bvc);
|
||||
if(!r)
|
||||
{
|
||||
LOG_ERROR("Failed to push ex-main chain blocks to alternative chain ");
|
||||
rollback_blockchain_switching(disconnected_chain, split_height);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -701,6 +704,22 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
|
|||
{
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
|
||||
uint64_t block_height = get_block_height(b);
|
||||
if(0 == block_height)
|
||||
{
|
||||
LOG_ERROR("Block with id: " << string_tools::pod_to_hex(id) << " (as alternative) have wrong miner transaction");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
if (!m_checkpoints.is_alternative_block_allowed(get_current_blockchain_height(), block_height))
|
||||
{
|
||||
LOG_PRINT_RED_L0("Block with id: " << id
|
||||
<< ENDL << " can't be accepted for alternative chain, block height: " << block_height
|
||||
<< ENDL << " blockchain height: " << get_current_blockchain_height());
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//block is not related with head of main chain
|
||||
//first of all - look in alternative chains container
|
||||
auto it_main_prev = m_blocks_index.find(b.prev_id);
|
||||
|
@ -746,31 +765,28 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
|
|||
block_extended_info bei = boost::value_initialized<block_extended_info>();
|
||||
bei.bl = b;
|
||||
bei.height = alt_chain.size() ? it_prev->second.height + 1 : it_main_prev->second + 1;
|
||||
|
||||
bool is_a_checkpoint;
|
||||
if(!m_checkpoints.check_block(bei.height, id, is_a_checkpoint))
|
||||
{
|
||||
LOG_ERROR("CHECKPOINT VALIDATION FAILED");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Always check PoW for alternative blocks
|
||||
m_is_in_checkpoint_zone = false;
|
||||
difficulty_type current_diff = get_next_difficulty_for_alternative_chain(alt_chain, bei);
|
||||
CHECK_AND_ASSERT_MES(current_diff, false, "!!!!!!! DIFFICULTY OVERHEAD !!!!!!!");
|
||||
crypto::hash proof_of_work = null_hash;
|
||||
if(!m_checkpoints.is_in_checkpoint_zone(bei.height))
|
||||
get_block_longhash(bei.bl, proof_of_work, bei.height);
|
||||
if(!check_hash(proof_of_work, current_diff))
|
||||
{
|
||||
m_is_in_checkpoint_zone = false;
|
||||
get_block_longhash(bei.bl, proof_of_work, bei.height);
|
||||
|
||||
if(!check_hash(proof_of_work, current_diff))
|
||||
{
|
||||
LOG_PRINT_RED_L0("Block with id: " << id
|
||||
<< ENDL << " for alternative chain, have not enough proof of work: " << proof_of_work
|
||||
<< ENDL << " expected difficulty: " << current_diff);
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
}else
|
||||
{
|
||||
m_is_in_checkpoint_zone = true;
|
||||
if(!m_checkpoints.check_block(bei.height, id))
|
||||
{
|
||||
LOG_ERROR("CHECKPOINT VALIDATION FAILED");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
LOG_PRINT_RED_L0("Block with id: " << id
|
||||
<< ENDL << " for alternative chain, have not enough proof of work: " << proof_of_work
|
||||
<< ENDL << " expected difficulty: " << current_diff);
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!prevalidate_miner_transaction(b, bei.height))
|
||||
|
@ -792,22 +808,33 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
|
|||
auto i_res = m_alternative_chains.insert(blocks_ext_by_hash::value_type(id, bei));
|
||||
CHECK_AND_ASSERT_MES(i_res.second, false, "insertion of new alternative block returned as it already exist");
|
||||
alt_chain.push_back(i_res.first);
|
||||
//check if difficulty bigger then in main chain
|
||||
if(m_blocks.back().cumulative_difficulty < bei.cumulative_difficulty)
|
||||
|
||||
if(is_a_checkpoint)
|
||||
{
|
||||
//do reorganize!
|
||||
LOG_PRINT_GREEN("###### REORGANIZE on height: " << alt_chain.front()->second.height << " of " << m_blocks.size() -1 << " with cum_difficulty " << m_blocks.back().cumulative_difficulty
|
||||
<< ENDL << " alternative blockchain size: " << alt_chain.size() << " with cum_difficulty " << bei.cumulative_difficulty, LOG_LEVEL_0);
|
||||
bool r = switch_to_alternative_blockchain(alt_chain);
|
||||
LOG_PRINT_GREEN("###### REORGANIZE on height: " << alt_chain.front()->second.height << " of " << m_blocks.size() - 1 <<
|
||||
", checkpoint is found in alternative chain on height " << bei.height, LOG_LEVEL_0);
|
||||
bool r = switch_to_alternative_blockchain(alt_chain, true);
|
||||
if(r) bvc.m_added_to_main_chain = true;
|
||||
else bvc.m_verifivation_failed = true;
|
||||
return r;
|
||||
}else if(m_blocks.back().cumulative_difficulty < bei.cumulative_difficulty) //check if difficulty bigger then in main chain
|
||||
{
|
||||
//do reorganize!
|
||||
LOG_PRINT_GREEN("###### REORGANIZE on height: " << alt_chain.front()->second.height << " of " << m_blocks.size() - 1 << " with cum_difficulty " << m_blocks.back().cumulative_difficulty
|
||||
<< ENDL << " alternative blockchain size: " << alt_chain.size() << " with cum_difficulty " << bei.cumulative_difficulty, LOG_LEVEL_0);
|
||||
bool r = switch_to_alternative_blockchain(alt_chain, false);
|
||||
if(r) bvc.m_added_to_main_chain = true;
|
||||
else bvc.m_verifivation_failed = true;
|
||||
return r;
|
||||
}else
|
||||
{
|
||||
LOG_PRINT_BLUE("----- BLOCK ADDED AS ALTERNATIVE ON HEIGHT " << bei.height
|
||||
<< ENDL << "id:\t" << id
|
||||
<< ENDL << "PoW:\t" << proof_of_work
|
||||
<< ENDL << "difficulty:\t" << current_diff, LOG_LEVEL_0);
|
||||
return true;
|
||||
}
|
||||
LOG_PRINT_BLUE("----- BLOCK ADDED AS ALTERNATIVE ON HEIGHT " << bei.height
|
||||
<< ENDL << "id:\t" << id
|
||||
<< ENDL << "PoW:\t" << proof_of_work
|
||||
<< ENDL << "difficulty:\t" << current_diff, LOG_LEVEL_0);
|
||||
return true;
|
||||
}else
|
||||
{
|
||||
//block orphaned
|
||||
|
@ -815,7 +842,6 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
|
|||
LOG_PRINT_RED_L0("Block recognized as orphaned and rejected, id = " << id);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace cryptonote
|
|||
uint64_t already_generated_coins;
|
||||
};
|
||||
|
||||
blockchain_storage(tx_memory_pool& tx_pool):m_tx_pool(tx_pool), m_current_block_cumul_sz_limit(0), m_is_in_checkpoint_zone(false)
|
||||
blockchain_storage(tx_memory_pool& tx_pool):m_tx_pool(tx_pool), m_current_block_cumul_sz_limit(0), m_is_in_checkpoint_zone(false), m_is_blockchain_storing(false)
|
||||
{};
|
||||
|
||||
bool init() { return init(tools::get_default_data_dir()); }
|
||||
|
@ -186,7 +186,7 @@ namespace cryptonote
|
|||
std::atomic<bool> m_is_in_checkpoint_zone;
|
||||
std::atomic<bool> m_is_blockchain_storing;
|
||||
|
||||
bool switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::iterator>& alt_chain);
|
||||
bool switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::iterator>& alt_chain, bool discard_disconnected_chain);
|
||||
bool pop_block_from_blockchain();
|
||||
bool purge_block_data_from_blockchain(const block& b, size_t processed_tx_count);
|
||||
bool purge_transaction_from_blockchain(const crypto::hash& tx_id);
|
||||
|
|
|
@ -29,10 +29,11 @@ namespace cryptonote
|
|||
return !m_points.empty() && (height <= (--m_points.end())->first);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool checkpoints::check_block(uint64_t height, const crypto::hash& h) const
|
||||
bool checkpoints::check_block(uint64_t height, const crypto::hash& h, bool& is_a_checkpoint) const
|
||||
{
|
||||
auto it = m_points.find(height);
|
||||
if(it == m_points.end())
|
||||
is_a_checkpoint = it != m_points.end();
|
||||
if(!is_a_checkpoint)
|
||||
return true;
|
||||
|
||||
if(it->second == h)
|
||||
|
@ -45,4 +46,25 @@ namespace cryptonote
|
|||
return false;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool checkpoints::check_block(uint64_t height, const crypto::hash& h) const
|
||||
{
|
||||
bool ignored;
|
||||
return check_block(height, h, ignored);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool checkpoints::is_alternative_block_allowed(uint64_t blockchain_height, uint64_t block_height) const
|
||||
{
|
||||
if (0 == block_height)
|
||||
return false;
|
||||
|
||||
auto it = m_points.upper_bound(blockchain_height);
|
||||
// Is blockchain_height before the first checkpoint?
|
||||
if (it == m_points.begin())
|
||||
return true;
|
||||
|
||||
--it;
|
||||
uint64_t checkpoint_height = it->first;
|
||||
return checkpoint_height < block_height;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,9 @@ namespace cryptonote
|
|||
bool add_checkpoint(uint64_t height, const std::string& hash_str);
|
||||
bool is_in_checkpoint_zone(uint64_t height) const;
|
||||
bool check_block(uint64_t height, const crypto::hash& h) const;
|
||||
bool check_block(uint64_t height, const crypto::hash& h, bool& is_a_checkpoint) const;
|
||||
bool is_alternative_block_allowed(uint64_t blockchain_height, uint64_t block_height) const;
|
||||
|
||||
private:
|
||||
std::map<uint64_t, crypto::hash> m_points;
|
||||
};
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace cryptonote {
|
|||
ADD_CHECKPOINT(453537, "d17de6916c5aa6ffcae575309c80b0f8fdcd0a84b5fa8e41a841897d4b5a4e97");
|
||||
ADD_CHECKPOINT(462250, "13468d210a5ec884cf839f0259f247ccf3efef0414ac45172033d32c739beb3e");
|
||||
ADD_CHECKPOINT(468000, "251bcbd398b1f593193a7210934a3d87f692b2cb0c45206150f59683dd7e9ba1");
|
||||
ADD_CHECKPOINT(480200, "363544ac9920c778b815c2fdbcbca70a0d79b21f662913a42da9b49e859f0e5b");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -502,7 +502,7 @@ namespace cryptonote
|
|||
LOG_PRINT_L0(ENDL << "**********************************************************************" << ENDL
|
||||
<< "The daemon will start synchronizing with the network. It may take up to several hours." << ENDL
|
||||
<< ENDL
|
||||
<< "You can set the level of process detailization by using command \"set_log <level>\", where <level> is either 0 (no details), 1 (current block height synchronized), or 2 (all details)." << ENDL
|
||||
<< "You can set the level of process detailization* through \"set_log <level>\" command*, where <level> is between 0 (no details) and 4 (very verbose)." << ENDL
|
||||
<< ENDL
|
||||
<< "Use \"help\" command to see the list of available commands." << ENDL
|
||||
<< ENDL
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <boost/atomic.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <atomic>
|
||||
#include "cryptonote_basic.h"
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define TX_EXTRA_TAG_PADDING 0x00
|
||||
#define TX_EXTRA_TAG_PUBKEY 0x01
|
||||
#define TX_EXTRA_NONCE 0x02
|
||||
#define TX_EXTRA_MERGE_MINING_TAG 0x03
|
||||
|
||||
#define TX_EXTRA_NONCE_PAYMENT_ID 0x00
|
||||
|
||||
|
@ -82,13 +83,62 @@ namespace cryptonote
|
|||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
struct tx_extra_merge_mining_tag
|
||||
{
|
||||
struct serialize_helper
|
||||
{
|
||||
tx_extra_merge_mining_tag& mm_tag;
|
||||
|
||||
serialize_helper(tx_extra_merge_mining_tag& mm_tag_) : mm_tag(mm_tag_)
|
||||
{
|
||||
}
|
||||
|
||||
BEGIN_SERIALIZE()
|
||||
VARINT_FIELD_N("depth", mm_tag.depth)
|
||||
FIELD_N("merkle_root", mm_tag.merkle_root)
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
size_t depth;
|
||||
crypto::hash merkle_root;
|
||||
|
||||
// load
|
||||
template <template <bool> class Archive>
|
||||
bool do_serialize(Archive<false>& ar)
|
||||
{
|
||||
std::string field;
|
||||
if(!::do_serialize(ar, field))
|
||||
return false;
|
||||
|
||||
std::istringstream iss(field);
|
||||
binary_archive<false> iar(iss);
|
||||
serialize_helper helper(*this);
|
||||
return ::serialization::serialize(iar, helper);
|
||||
}
|
||||
|
||||
// store
|
||||
template <template <bool> class Archive>
|
||||
bool do_serialize(Archive<true>& ar)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
binary_archive<true> oar(oss);
|
||||
serialize_helper helper(*this);
|
||||
if(!::do_serialize(oar, helper))
|
||||
return false;
|
||||
|
||||
std::string field = oss.str();
|
||||
return ::serialization::serialize(ar, field);
|
||||
}
|
||||
};
|
||||
|
||||
// tx_extra_field format, except tx_extra_padding and tx_extra_pub_key:
|
||||
// varint tag;
|
||||
// varint size;
|
||||
// varint data[];
|
||||
typedef boost::variant<tx_extra_padding, tx_extra_pub_key, tx_extra_nonce> tx_extra_field;
|
||||
typedef boost::variant<tx_extra_padding, tx_extra_pub_key, tx_extra_nonce, tx_extra_merge_mining_tag> tx_extra_field;
|
||||
}
|
||||
|
||||
VARIANT_TAG(binary_archive, cryptonote::tx_extra_padding, TX_EXTRA_TAG_PADDING);
|
||||
VARIANT_TAG(binary_archive, cryptonote::tx_extra_pub_key, TX_EXTRA_TAG_PUBKEY);
|
||||
VARIANT_TAG(binary_archive, cryptonote::tx_extra_nonce, TX_EXTRA_NONCE);
|
||||
VARIANT_TAG(binary_archive, cryptonote::tx_extra_merge_mining_tag, TX_EXTRA_MERGE_MINING_TAG);
|
||||
|
|
|
@ -108,9 +108,12 @@ namespace cryptonote
|
|||
return true;
|
||||
}
|
||||
|
||||
LOG_PRINT_CCONTEXT_YELLOW("Sync data returned unknown top block: " << m_core.get_current_blockchain_height() << "->" << hshd.current_height
|
||||
<< "[" << static_cast<int64_t>(hshd.current_height - m_core.get_current_blockchain_height()) << " blocks(" << (hshd.current_height - m_core.get_current_blockchain_height()) /720 << " days) behind] " << ENDL
|
||||
<< "remote top: " << hshd.top_id << "[" << hshd.current_height << "]" << ", set SYNCHRONIZATION mode", (is_inital ? LOG_LEVEL_0:LOG_LEVEL_1));
|
||||
int64_t diff = static_cast<int64_t>(hshd.current_height) - static_cast<int64_t>(m_core.get_current_blockchain_height());
|
||||
LOG_PRINT_CCONTEXT_YELLOW("Sync data returned unknown top block: " << m_core.get_current_blockchain_height() << " -> " << hshd.current_height
|
||||
<< " [" << std::abs(diff) << " blocks (" << diff / (24 * 60 * 60 / DIFFICULTY_TARGET) << " days) "
|
||||
<< (0 <= diff ? std::string("behind") : std::string("ahead"))
|
||||
<< "] " << ENDL << "SYNCHRONIZATION started", (is_inital ? LOG_LEVEL_0:LOG_LEVEL_1));
|
||||
LOG_PRINT_L1("Remote top block height: " << hshd.current_height << ", id: " << hshd.top_id);
|
||||
context.m_state = cryptonote_connection_context::state_synchronizing;
|
||||
context.m_remote_blockchain_height = hshd.current_height;
|
||||
//let the socket to send response to handshake, but request callback, to let send request data after response
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
|
||||
#include "common/util.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
class daemon_cmmands_handler
|
||||
|
@ -34,6 +35,7 @@ public:
|
|||
m_cmd_binder.set_handler("show_hr", boost::bind(&daemon_cmmands_handler::show_hr, this, _1), "Start showing hash rate");
|
||||
m_cmd_binder.set_handler("hide_hr", boost::bind(&daemon_cmmands_handler::hide_hr, this, _1), "Stop showing hash rate");
|
||||
m_cmd_binder.set_handler("save", boost::bind(&daemon_cmmands_handler::save, this, _1), "Save blockchain");
|
||||
m_cmd_binder.set_handler("set_log", boost::bind(&daemon_cmmands_handler::set_log, this, _1), "set_log <level> - Change current log detalization level, <level> is a number 0-4");
|
||||
}
|
||||
|
||||
bool start_handling()
|
||||
|
@ -54,6 +56,7 @@ private:
|
|||
std::string get_commands_str()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << CRYPTONOTE_NAME << " v" << PROJECT_VERSION_LONG << ENDL;
|
||||
ss << "Commands: " << ENDL;
|
||||
std::string usage = m_cmd_binder.get_usage();
|
||||
boost::replace_all(usage, "\n", "\n ");
|
||||
|
@ -123,19 +126,34 @@ private:
|
|||
return false;
|
||||
}
|
||||
uint64_t start_index = 0;
|
||||
uint64_t end_index = 0;
|
||||
uint64_t end_block_parametr = m_srv.get_payload_object().get_core().get_current_blockchain_height();
|
||||
if(!string_tools::get_xtype_from_string(start_index, args[0]))
|
||||
{
|
||||
std::cout << "wrong starter block index parameter" << ENDL;
|
||||
return false;
|
||||
}
|
||||
if(args.size() >1 && !string_tools::get_xtype_from_string(end_block_parametr, args[1]))
|
||||
if(args.size() >1 && !string_tools::get_xtype_from_string(end_index, args[1]))
|
||||
{
|
||||
std::cout << "wrong end block index parameter" << ENDL;
|
||||
return false;
|
||||
}
|
||||
if (end_index == 0)
|
||||
{
|
||||
end_index = end_block_parametr;
|
||||
}
|
||||
if (end_index > end_block_parametr)
|
||||
{
|
||||
std::cout << "end block index parameter shouldn't be greater than " << end_block_parametr << ENDL;
|
||||
return false;
|
||||
}
|
||||
if (end_index <= start_index)
|
||||
{
|
||||
std::cout << "end block index should be greater than starter block index" << ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_srv.get_payload_object().get_core().print_blockchain(start_index, end_block_parametr);
|
||||
m_srv.get_payload_object().get_core().print_blockchain(start_index, end_index);
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
|
@ -144,6 +162,33 @@ private:
|
|||
m_srv.get_payload_object().get_core().print_blockchain_index();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool set_log(const std::vector<std::string>& args)
|
||||
{
|
||||
if(args.size() != 1)
|
||||
{
|
||||
std::cout << "use: set_log <log_level_number_0-4>" << ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t l = 0;
|
||||
if(!string_tools::get_xtype_from_string(l, args[0]))
|
||||
{
|
||||
std::cout << "wrong number format, use: set_log <log_level_number_0-4>" << ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(LOG_LEVEL_4 < l)
|
||||
{
|
||||
std::cout << "wrong number range, use: set_log <log_level_number_0-4>" << ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
log_space::log_singletone::get_set_log_detalisation_level(true, l);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
static bool print_as_json(T& obj)
|
||||
|
|
|
@ -109,7 +109,7 @@ namespace mining
|
|||
if(!m_http_client.is_connected())
|
||||
{
|
||||
LOG_PRINT_L0("Connecting " << m_pool_ip << ":" << m_pool_port << "....");
|
||||
if(!m_http_client.connect(m_pool_ip, m_pool_port, 1000))
|
||||
if(!m_http_client.connect(m_pool_ip, m_pool_port, 20000))
|
||||
{
|
||||
LOG_PRINT_L0("Failed to connect " << m_pool_ip << ":" << m_pool_port << ", sleep....");
|
||||
epee::misc_utils::sleep_no_w(1000);
|
||||
|
@ -198,7 +198,7 @@ namespace mining
|
|||
LOG_PRINT_L0("Can't get new job! Disconnect and sleep....");
|
||||
m_http_client.disconnect();
|
||||
epee::misc_utils::sleep_no_w(1000);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (getjob_response.blob.empty() && getjob_response.target.empty() && getjob_response.job_id.empty())
|
||||
{
|
||||
|
|
|
@ -146,6 +146,7 @@ namespace nodetool
|
|||
template<class t_callback>
|
||||
bool try_ping(basic_node_data& node_data, p2p_connection_context& context, t_callback cb);
|
||||
bool make_expected_connections_count(bool white_list, size_t expected_connections);
|
||||
bool is_priority_node(const net_address& na);
|
||||
|
||||
//debug functions
|
||||
std::string print_connections_container();
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "version.h"
|
||||
#include "string_tools.h"
|
||||
#include "common/command_line.h"
|
||||
|
@ -405,10 +407,10 @@ namespace nodetool
|
|||
hsh_result = false;
|
||||
return;
|
||||
}
|
||||
LOG_PRINT_CCONTEXT_L0(" COMMAND_HANDSHAKE INVOKED OK");
|
||||
LOG_PRINT_CCONTEXT_L1(" COMMAND_HANDSHAKE INVOKED OK");
|
||||
}else
|
||||
{
|
||||
LOG_PRINT_CCONTEXT_L0(" COMMAND_HANDSHAKE(AND CLOSE) INVOKED OK");
|
||||
LOG_PRINT_CCONTEXT_L1(" COMMAND_HANDSHAKE(AND CLOSE) INVOKED OK");
|
||||
}
|
||||
}, P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT);
|
||||
|
||||
|
@ -419,7 +421,7 @@ namespace nodetool
|
|||
|
||||
if(!hsh_result)
|
||||
{
|
||||
LOG_PRINT_CC_L0(context_, "COMMAND_HANDSHAKE Failed");
|
||||
LOG_PRINT_CC_L1(context_, "COMMAND_HANDSHAKE Failed");
|
||||
m_net_server.get_config_object().close(context_.m_connection_id);
|
||||
}
|
||||
|
||||
|
@ -510,36 +512,53 @@ namespace nodetool
|
|||
return connected;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
#define LOG_PRINT_CC_PRIORITY_NODE(priority, con, msg) \
|
||||
do { \
|
||||
if (priority) {\
|
||||
LOG_PRINT_CC_L0(con, msg); \
|
||||
} else {\
|
||||
LOG_PRINT_CC_L1(con, msg); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::try_to_connect_and_handshake_with_new_peer(const net_address& na, bool just_take_peerlist, uint64_t last_seen_stamp, bool white)
|
||||
{
|
||||
LOG_PRINT_L0("Connecting to " << string_tools::get_ip_string_from_int32(na.ip) << ":" << string_tools::num_to_string_fast(na.port) << "(white=" << white << ", last_seen: " << (last_seen_stamp?misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never" ) << ")...");
|
||||
LOG_PRINT_L1("Connecting to " << string_tools::get_ip_string_from_int32(na.ip) << ":"
|
||||
<< string_tools::num_to_string_fast(na.port) << "(white=" << white << ", last_seen: "
|
||||
<< (last_seen_stamp?misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never")
|
||||
<< ")...");
|
||||
|
||||
typename net_server::t_connection_context con = AUTO_VAL_INIT(con);
|
||||
bool res = m_net_server.connect(string_tools::get_ip_string_from_int32(na.ip),
|
||||
string_tools::num_to_string_fast(na.port),
|
||||
m_config.m_net_config.connection_timeout,
|
||||
con);
|
||||
|
||||
if(!res)
|
||||
{
|
||||
LOG_PRINT_L0("Connect failed to "
|
||||
bool is_priority = is_priority_node(na);
|
||||
LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Connect failed to "
|
||||
<< string_tools::get_ip_string_from_int32(na.ip)
|
||||
<< ":" << string_tools::num_to_string_fast(na.port)
|
||||
/*<< ", try " << try_count*/);
|
||||
//m_peerlist.set_peer_unreachable(pe);
|
||||
return false;
|
||||
}
|
||||
|
||||
peerid_type pi = AUTO_VAL_INIT(pi);
|
||||
res = do_handshake_with_peer(pi, con, just_take_peerlist);
|
||||
|
||||
if(!res)
|
||||
{
|
||||
LOG_PRINT_CC_L0(con, "Failed to HANDSHAKE with peer "
|
||||
bool is_priority = is_priority_node(na);
|
||||
LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Failed to HANDSHAKE with peer "
|
||||
<< string_tools::get_ip_string_from_int32(na.ip)
|
||||
<< ":" << string_tools::num_to_string_fast(na.port)
|
||||
/*<< ", try " << try_count*/);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(just_take_peerlist)
|
||||
{
|
||||
m_net_server.get_config_object().close(con.m_connection_id);
|
||||
|
@ -557,6 +576,9 @@ namespace nodetool
|
|||
LOG_PRINT_CC_GREEN(con, "CONNECTION HANDSHAKED OK.", LOG_LEVEL_2);
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef LOG_PRINT_CC_PRIORITY_NODE
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::make_new_connection_from_peerlist(bool use_white_list)
|
||||
|
@ -1095,5 +1117,10 @@ namespace nodetool
|
|||
{
|
||||
LOG_PRINT_L2("["<< net_utils::print_connection_context(context) << "] CLOSE CONNECTION");
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::is_priority_node(const net_address& na)
|
||||
{
|
||||
return std::find(m_priority_peers.begin(), m_priority_peers.end(), na) != m_priority_peers.end();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,8 +79,10 @@ inline bool do_serialize(Archive &ar, T &v)
|
|||
if (!r || !ar.stream().good()) return false; \
|
||||
} while(0);
|
||||
#define FIELDS(f) \
|
||||
do { \
|
||||
bool r = ::do_serialize(ar, f); \
|
||||
if (!r || !ar.stream().good()) return false;
|
||||
if (!r || !ar.stream().good()) return false; \
|
||||
} while(0);
|
||||
#define FIELD(f) \
|
||||
do { \
|
||||
ar.tag(#f); \
|
||||
|
@ -93,6 +95,12 @@ inline bool do_serialize(Archive &ar, T &v)
|
|||
ar.serialize_varint(f); \
|
||||
if (!ar.stream().good()) return false; \
|
||||
} while(0);
|
||||
#define VARINT_FIELD_N(t, f) \
|
||||
do { \
|
||||
ar.tag(t); \
|
||||
ar.serialize_varint(f); \
|
||||
if (!ar.stream().good()) return false; \
|
||||
} while(0);
|
||||
|
||||
namespace serialization {
|
||||
namespace detail
|
||||
|
|
|
@ -228,8 +228,8 @@ bool simple_wallet::ask_wallet_create_if_needed()
|
|||
wallet_path = string_tools::trim(wallet_path);
|
||||
|
||||
bool keys_file_exists;
|
||||
bool wallet_file_exitst;
|
||||
tools::wallet2::wallet_exists(wallet_path, keys_file_exists, wallet_file_exitst);
|
||||
bool wallet_file_exists;
|
||||
tools::wallet2::wallet_exists(wallet_path, keys_file_exists, wallet_file_exists);
|
||||
|
||||
bool r;
|
||||
if(keys_file_exists)
|
||||
|
@ -238,7 +238,7 @@ bool simple_wallet::ask_wallet_create_if_needed()
|
|||
r = true;
|
||||
}else
|
||||
{
|
||||
if(!wallet_file_exitst)
|
||||
if(!wallet_file_exists)
|
||||
{
|
||||
std::cout << "The wallet doesn't exist, generating new one" << std::endl;
|
||||
m_generate_new = wallet_path;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define BUILD_COMMIT_ID "@VERSION@"
|
||||
#define PROJECT_VERSION "0.8.7"
|
||||
#define PROJECT_VERSION_BUILD_NO "58"
|
||||
#define PROJECT_VERSION "0.8.8"
|
||||
#define PROJECT_VERSION_BUILD_NO "65"
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO "(" BUILD_COMMIT_ID ")"
|
||||
|
|
|
@ -455,14 +455,14 @@ void wallet2::generate(const std::string& wallet_, const std::string& password)
|
|||
store();
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exitst)
|
||||
void wallet2::wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exists)
|
||||
{
|
||||
std::string keys_file, wallet_file;
|
||||
do_prepare_file_names(file_path, keys_file, wallet_file);
|
||||
|
||||
boost::system::error_code ignore;
|
||||
keys_file_exists = boost::filesystem::exists(keys_file, ignore);
|
||||
wallet_file_exitst = boost::filesystem::exists(wallet_file, ignore);
|
||||
wallet_file_exists = boost::filesystem::exists(wallet_file, ignore);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::prepare_file_names(const std::string& file_path)
|
||||
|
|
|
@ -144,7 +144,7 @@ namespace tools
|
|||
a & m_payments;
|
||||
}
|
||||
|
||||
static void wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exitst);
|
||||
static void wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exists);
|
||||
|
||||
private:
|
||||
bool store_keys(const std::string& keys_file_name, const std::string& password);
|
||||
|
|
45
tests/performance_tests/cn_slow_hash.h
Normal file
45
tests/performance_tests/cn_slow_hash.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "crypto/crypto.h"
|
||||
#include "cryptonote_core/cryptonote_basic.h"
|
||||
|
||||
class test_cn_slow_hash
|
||||
{
|
||||
public:
|
||||
static const size_t loop_count = 10;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct data_t
|
||||
{
|
||||
char data[13];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static_assert(13 == sizeof(data_t), "Invalid structure size");
|
||||
|
||||
bool init()
|
||||
{
|
||||
if (!epee::string_tools::hex_to_pod("63617665617420656d70746f72", m_data))
|
||||
return false;
|
||||
|
||||
if (!epee::string_tools::hex_to_pod("bbec2cacf69866a8e740380fe7b818fc78f8571221742d729d9d02d7f8989b87", m_expected_hash))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test()
|
||||
{
|
||||
crypto::hash hash;
|
||||
crypto::cn_slow_hash(&m_data, sizeof(m_data), hash);
|
||||
return hash == m_expected_hash;
|
||||
}
|
||||
|
||||
private:
|
||||
data_t m_data;
|
||||
crypto::hash m_expected_hash;
|
||||
};
|
|
@ -8,6 +8,7 @@
|
|||
// tests
|
||||
#include "construct_tx.h"
|
||||
#include "check_ring_signature.h"
|
||||
#include "cn_slow_hash.h"
|
||||
#include "derive_public_key.h"
|
||||
#include "derive_secret_key.h"
|
||||
#include "generate_key_derivation.h"
|
||||
|
@ -56,6 +57,8 @@ int main(int argc, char** argv)
|
|||
TEST_PERFORMANCE0(test_derive_public_key);
|
||||
TEST_PERFORMANCE0(test_derive_secret_key);
|
||||
|
||||
TEST_PERFORMANCE0(test_cn_slow_hash);
|
||||
|
||||
std::cout << "Tests finished. Elapsed time: " << timer.elapsed_ms() / 1000 << " sec" << std::endl;
|
||||
|
||||
return 0;
|
||||
|
|
140
tests/unit_tests/checkpoints.cpp
Normal file
140
tests/unit_tests/checkpoints.cpp
Normal file
|
@ -0,0 +1,140 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "cryptonote_core/checkpoints.cpp"
|
||||
|
||||
using namespace cryptonote;
|
||||
|
||||
|
||||
TEST(checkpoints_is_alternative_block_allowed, handles_empty_checkpoins)
|
||||
{
|
||||
checkpoints cp;
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(0, 0));
|
||||
|
||||
ASSERT_TRUE(cp.is_alternative_block_allowed(1, 1));
|
||||
ASSERT_TRUE(cp.is_alternative_block_allowed(1, 9));
|
||||
ASSERT_TRUE(cp.is_alternative_block_allowed(9, 1));
|
||||
}
|
||||
|
||||
TEST(checkpoints_is_alternative_block_allowed, handles_one_checkpoint)
|
||||
{
|
||||
checkpoints cp;
|
||||
cp.add_checkpoint(5, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(0, 0));
|
||||
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 1));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 4));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 9));
|
||||
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 1));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 4));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 9));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(5, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(5, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(5, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(5, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(5, 9));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(6, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(6, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(6, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(6, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(6, 9));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(9, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(9, 9));
|
||||
}
|
||||
|
||||
TEST(checkpoints_is_alternative_block_allowed, handles_two_and_more_checkpoints)
|
||||
{
|
||||
checkpoints cp;
|
||||
cp.add_checkpoint(5, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
cp.add_checkpoint(9, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(0, 0));
|
||||
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 1));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 4));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 8));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 11));
|
||||
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 1));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 4));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 8));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 11));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(5, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(5, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(5, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(5, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(5, 8));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(5, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(5, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(5, 11));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(6, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(6, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(6, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(6, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(6, 8));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(6, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(6, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(6, 11));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(8, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(8, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(8, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(8, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(8, 8));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(8, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(8, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(8, 11));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 5));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 6));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 8));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(9, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(9, 11));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(10, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(10, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(10, 5));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(10, 6));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(10, 8));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(10, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(10, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(10, 11));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(11, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(11, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(11, 5));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(11, 6));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(11, 8));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(11, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(11, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(11, 11));
|
||||
}
|
Loading…
Reference in a new issue