1
0
Fork 0
forked from lthn/blockchain

Merge branch 'master' into offsig

# Conflicts:
#	tests/unit_tests/epee_levin_protocol_handler_async.cpp
This commit is contained in:
sowle 2019-04-19 15:46:53 +03:00
commit d51664e5dc
38 changed files with 904 additions and 313 deletions

View file

@ -51,6 +51,7 @@ namespace math_helper
average()
{
m_base = default_base;
m_count = 0;
}
bool set_base()
@ -71,6 +72,7 @@ namespace math_helper
CRITICAL_REGION_LOCAL(m_lock);
//#ifndef DEBUG_STUB
m_count++;
m_list.push_back(vl);
if(m_list.size() > m_base )
m_list.pop_front();
@ -106,9 +108,20 @@ namespace math_helper
return 0;
}
uint64_t& get_count()
{
return m_count;
}
void reset()
{
m_count = 0;
m_list.clear();
}
private:
unsigned int m_base;
unsigned int m_base;
uint64_t m_count;
std::list<value_type> m_list;
mutable critical_section m_lock;
};

View file

@ -75,15 +75,18 @@ namespace tools
std::map<std::thread::id, std::vector<bool> > m_transactions_stack;
std::atomic<bool> m_is_open;
epee::shared_recursive_mutex& m_rwlock;
public:
struct performance_data
{
epee::math_helper::average<uint64_t, 10> backend_set_pod_time;
epee::math_helper::average<uint64_t, 10> backend_set_t_time;
epee::math_helper::average<uint64_t, 10> set_serialize_t_time;
epee::math_helper::average<uint64_t, 10> backend_get_pod_time;
epee::math_helper::average<uint64_t, 10> backend_get_t_time;
epee::math_helper::average<uint64_t, 10> get_serialize_t_time;
};
private:
mutable performance_data m_gperformance_data;
mutable std::unordered_map<container_handle, performance_data> m_performance_data_map;
public:
basic_db_accessor(std::shared_ptr<i_db_backend> backend, epee::shared_recursive_mutex& rwlock) :m_backend(backend), m_rwlock(rwlock), m_is_open(false)
@ -93,7 +96,8 @@ namespace tools
close();
}
const performance_data& get_performance_data_for_handle(container_handle h) const { return m_performance_data_map[h]; }
performance_data& get_performance_data_for_handle(container_handle h) const { return m_performance_data_map[h]; }
performance_data& get_performance_data_global() const { return m_gperformance_data; }
bool bind_parent_container(i_db_parent_to_container_callabck* pcontainer)
@ -270,15 +274,23 @@ namespace tools
template<class t_pod_key, class t_object>
bool get_t_object(container_handle h, const t_pod_key& k, t_object& obj) const
{
performance_data& m_performance_data = m_gperformance_data;
//TRY_ENTRY();
std::string res_buff;
size_t sk = 0;
const char* pk = key_to_ptr(k, sk);
TIME_MEASURE_START_PD(backend_get_t_time);
if (!m_backend->get(h, pk, sk, res_buff))
return false;
TIME_MEASURE_FINISH_PD(backend_get_t_time);
return t_unserializable_object_from_blob(obj, res_buff);
TIME_MEASURE_START_PD(get_serialize_t_time);
bool res = t_unserializable_object_from_blob(obj, res_buff);
TIME_MEASURE_FINISH_PD(get_serialize_t_time);
return res;
//CATCH_ENTRY_L0("get_t_object_from_db", false);
}
@ -310,15 +322,18 @@ namespace tools
bool get_pod_object(container_handle h, const t_pod_key& k, t_pod_object& obj) const
{
static_assert(std::is_pod<t_pod_object>::value, "t_pod_object must be a POD type.");
performance_data& m_performance_data = m_gperformance_data;
//TRY_ENTRY();
std::string res_buff;
size_t sk = 0;
const char* pk = key_to_ptr(k, sk);
TIME_MEASURE_START_PD(backend_get_pod_time);
if (!m_backend->get(h, pk, sk, res_buff))
return false;
TIME_MEASURE_FINISH_PD(backend_get_pod_time);
CHECK_AND_ASSERT_MES(sizeof(t_pod_object) == res_buff.size(), false, "sizes missmath at get_pod_object_from_db(). returned size = "
<< res_buff.size() << "expected: " << sizeof(t_pod_object));
@ -784,14 +799,19 @@ namespace tools
m_cache.erase(k);
}
const performance_data& get_performance_data() const
performance_data& get_performance_data() const
{
return m_performance_data;
}
const typename basic_db_accessor::performance_data& get_performance_data_native() const
typename basic_db_accessor::performance_data& get_performance_data_native() const
{
return base_class::bdb.get_performance_data_for_handle(base_class::m_h);
}
typename basic_db_accessor::performance_data& get_performance_data_global() const
{
return base_class::bdb.get_performance_data_global();
}
private:
mutable performance_data m_performance_data;
};

View file

@ -567,6 +567,8 @@ bool handle_get_daemon_info(po::variables_map& vm)
<< "longhash_calculating_time_3: " << res.performance_data.longhash_calculating_time_3 << ENDL
<< "raise_block_core_event: " << res.performance_data.raise_block_core_event << ENDL
<< "target_calculating_time_2: " << res.performance_data.target_calculating_time_2 << ENDL
<< "target_calculating_enum_blocks: " << res.performance_data.target_calculating_enum_blocks << ENDL
<< "target_calculating_calc: " << res.performance_data.target_calculating_calc << ENDL
<< "all_txs_insert_time_5: " << res.performance_data.all_txs_insert_time_5 << ENDL
<< "tx_add_one_tx_time: " << res.performance_data.tx_add_one_tx_time << ENDL
<< "tx_check_inputs_time: " << res.performance_data.tx_check_inputs_time << ENDL

View file

@ -61,6 +61,7 @@ using namespace currency;
#define BLOCKCHAIN_STORAGE_OPTIONS_ID_STORAGE_MAJOR_COMPATIBILITY_VERSION 3 //mismatch here means full resync
#define BLOCKCHAIN_STORAGE_OPTIONS_ID_STORAGE_MINOR_COMPATIBILITY_VERSION 4 //mismatch here means some reinitializations
#define TARGETDATA_CACHE_SIZE DIFFICULTY_WINDOW + 10
DISABLE_VS_WARNINGS(4267)
@ -447,6 +448,8 @@ bool blockchain_storage::clear()
m_db_aliases.clear();
m_db_addr_to_alias.clear();
m_db_per_block_gindex_incs.clear();
m_pos_targetdata_cache.clear();
m_pow_targetdata_cache.clear();
m_db.commit_transaction();
@ -889,25 +892,28 @@ wide_difficulty_type blockchain_storage::get_next_diff_conditional(bool pos) con
CRITICAL_REGION_LOCAL(m_read_lock);
std::vector<uint64_t> timestamps;
std::vector<wide_difficulty_type> commulative_difficulties;
size_t count = 0;
if (!m_db_blocks.size())
return DIFFICULTY_STARTER;
//skip genesis timestamp
uint64_t stop_ind = 0;
uint64_t blocks_size = m_db_blocks.size();
for (uint64_t cur_ind = blocks_size - 1; cur_ind != stop_ind && count < DIFFICULTY_WINDOW; cur_ind--)
{
auto beiptr = m_db_blocks[cur_ind];
TIME_MEASURE_START_PD(target_calculating_enum_blocks);
std::list<std::pair<wide_difficulty_type, uint64_t>>& targetdata_cache = pos ? m_pos_targetdata_cache : m_pow_targetdata_cache;
if (targetdata_cache.empty())
load_targetdata_cache(pos);
bool is_pos_bl = is_pos_block(beiptr->bl);
if (pos != is_pos_bl)
continue;
timestamps.push_back(beiptr->bl.timestamp);
commulative_difficulties.push_back(beiptr->cumulative_diff_precise);
size_t count = 0;
for (auto it = targetdata_cache.rbegin(); it != targetdata_cache.rend() && count < DIFFICULTY_WINDOW; it++)
{
timestamps.push_back(it->second);
commulative_difficulties.push_back(it->first);
++count;
}
wide_difficulty_type& dif = pos ? m_cached_next_pos_difficulty : m_cached_next_pow_difficulty;
return dif = next_difficulty(timestamps, commulative_difficulties, pos ? DIFFICULTY_POS_TARGET : DIFFICULTY_POW_TARGET);
TIME_MEASURE_FINISH_PD(target_calculating_enum_blocks);
TIME_MEASURE_START_PD(target_calculating_calc);
dif = next_difficulty(timestamps, commulative_difficulties, pos ? DIFFICULTY_POS_TARGET : DIFFICULTY_POW_TARGET);
TIME_MEASURE_FINISH_PD(target_calculating_calc);
return dif;
}
//------------------------------------------------------------------
wide_difficulty_type blockchain_storage::get_next_diff_conditional2(bool pos, const alt_chain_type& alt_chain, uint64_t split_height) const
@ -4542,37 +4548,81 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
<< ENDL << "HEIGHT " << bei.height << ", difficulty: " << current_diffic << ", cumul_diff_precise: " << bei.cumulative_diff_precise << ", cumul_diff_adj: " << bei.cumulative_diff_adjusted << " (+" << cumulative_diff_delta << ")"
<< ENDL << "block reward: " << print_money_brief(base_reward + fee_summary) << " (" << print_money_brief(base_reward) << " + " << print_money_brief(fee_summary)
<< ")" << ", coinbase_blob_size: " << coinbase_blob_size << ", cumulative size: " << cumulative_block_size << ", tx_count: " << bei.bl.tx_hashes.size()
<< ", " << block_processing_time_0_ms
<< "(" << block_processing_time_1
<< "/" << target_calculating_time_2
<< ", timing: " << block_processing_time_0_ms << "ms"
<< "(micrsec:" << block_processing_time_1
<< "(" << target_calculating_time_2 << "(" << m_performance_data.target_calculating_enum_blocks.get_last_val() << "/" << m_performance_data.target_calculating_calc.get_last_val() << ")"
<< "/" << longhash_calculating_time_3
<< "/" << insert_time_4
<< "/" << all_txs_insert_time_5
<< "/" << etc_stuff_6
<< ")micrs");
<< "))");
on_block_added(bei, id);
bvc.m_added_to_main_chain = true;
return true;
}
//------------------------------------------------------------------
void blockchain_storage::on_block_added(const block_extended_info& bei, const crypto::hash& id)
{
update_next_comulative_size_limit();
m_timestamps_median_cache.clear();
m_tx_pool.on_blockchain_inc(bei.height, id);
update_targetdata_cache_on_block_added(bei);
TIME_MEASURE_START_PD(raise_block_core_event);
rise_core_event(CORE_EVENT_BLOCK_ADDED, void_struct());
TIME_MEASURE_FINISH_PD(raise_block_core_event);
}
//------------------------------------------------------------------
void blockchain_storage::on_block_removed(const block_extended_info& bei)
{
m_tx_pool.on_blockchain_dec(m_db_blocks.size() - 1, get_top_block_id());
m_timestamps_median_cache.clear();
update_targetdata_cache_on_block_removed(bei);
LOG_PRINT_L2("block at height " << bei.height << " was removed from the blockchain");
}
//------------------------------------------------------------------
void blockchain_storage::update_targetdata_cache_on_block_added(const block_extended_info& bei)
{
if (bei.height == 0)
return; //skip genesis
std::list<std::pair<wide_difficulty_type, uint64_t>>& targetdata_cache = is_pos_block(bei.bl) ? m_pos_targetdata_cache : m_pow_targetdata_cache;
targetdata_cache.push_back(std::pair<wide_difficulty_type, uint64_t>(bei.cumulative_diff_precise, bei.bl.timestamp));
while (targetdata_cache.size() > TARGETDATA_CACHE_SIZE)
targetdata_cache.pop_front();
}
//------------------------------------------------------------------
void blockchain_storage::update_targetdata_cache_on_block_removed(const block_extended_info& bei)
{
std::list<std::pair<wide_difficulty_type, uint64_t>>& targetdata_cache = is_pos_block(bei.bl) ? m_pos_targetdata_cache : m_pow_targetdata_cache;
if (targetdata_cache.size())
targetdata_cache.pop_back();
if (targetdata_cache.size() < DIFFICULTY_WINDOW)
targetdata_cache.clear();
}
//------------------------------------------------------------------
void blockchain_storage::load_targetdata_cache(bool is_pos)const
{
std::list<std::pair<wide_difficulty_type, uint64_t>>& targetdata_cache = is_pos? m_pos_targetdata_cache: m_pow_targetdata_cache;
targetdata_cache.clear();
uint64_t stop_ind = 0;
uint64_t blocks_size = m_db_blocks.size();
size_t count = 0;
for (uint64_t cur_ind = blocks_size - 1; cur_ind != stop_ind && count < DIFFICULTY_WINDOW + 5; cur_ind--)
{
auto beiptr = m_db_blocks[cur_ind];
bool is_pos_bl = is_pos_block(beiptr->bl);
if (is_pos != is_pos_bl)
continue;
targetdata_cache.push_front(std::pair<wide_difficulty_type, uint64_t>(beiptr->cumulative_diff_precise, beiptr->bl.timestamp));
++count;
}
}
//------------------------------------------------------------------
void blockchain_storage::on_abort_transaction()
{
if (m_event_handler) m_event_handler->on_clear_events();

View file

@ -68,6 +68,9 @@ namespace currency
epee::math_helper::average<uint64_t, 5> etc_stuff_6;
epee::math_helper::average<uint64_t, 5> insert_time_4;
epee::math_helper::average<uint64_t, 5> raise_block_core_event;
//target_calculating_time_2
epee::math_helper::average<uint64_t, 5> target_calculating_enum_blocks;
epee::math_helper::average<uint64_t, 5> target_calculating_calc;
//tx processing zone
epee::math_helper::average<uint64_t, 5> tx_check_inputs_time;
@ -498,7 +501,7 @@ namespace currency
mutable core_runtime_config m_core_runtime_config;
mutable i_core_event_handler* m_event_handler;
mutable i_core_event_handler m_event_handler_stub;
//tools::median_db_cache<uint64_t, uint64_t> m_tx_fee_median;
mutable std::unordered_map<size_t, uint64_t> m_timestamps_median_cache;
mutable performnce_data m_performance_data;
@ -507,7 +510,10 @@ namespace currency
//just informational
mutable wide_difficulty_type m_cached_next_pow_difficulty;
mutable wide_difficulty_type m_cached_next_pos_difficulty;
//work like a cache to avoid
mutable std::list <std::pair<wide_difficulty_type, uint64_t>> m_pos_targetdata_cache;
mutable std::list <std::pair<wide_difficulty_type, uint64_t>> m_pow_targetdata_cache;
//work like a cache to avoid recalculation on read operations
mutable uint64_t m_current_fee_median;
mutable uint64_t m_current_fee_median_effective_index;
bool m_is_reorganize_in_process;
@ -557,9 +563,12 @@ namespace currency
const std::vector<txin_etc_details_v>& get_txin_etc_options(const txin_v& in)const;
void on_block_added(const block_extended_info& bei, const crypto::hash& id);
void on_block_removed(const block_extended_info& bei);
void update_targetdata_cache_on_block_added(const block_extended_info& bei);
void update_targetdata_cache_on_block_removed(const block_extended_info& bei);
uint64_t tx_fee_median_for_height(uint64_t h) const;
uint64_t get_tx_fee_median_effective_index(uint64_t h) const;
void on_abort_transaction();
void load_targetdata_cache(bool is_pos) const;
uint64_t get_adjusted_time()const;

View file

@ -55,23 +55,7 @@ namespace currency {
return a + b < a || (c && a + b == (uint64_t)-1);
}
bool check_hash_old(const crypto::hash &hash, difficulty_type difficulty) {
uint64_t low, high, top, cur;
// First check the highest word, this will most likely fail for a random hash.
mul(swap64le(((const uint64_t *)&hash)[3]), difficulty, top, high);
if (high != 0) {
return false;
}
mul(swap64le(((const uint64_t *)&hash)[0]), difficulty, low, cur);
mul(swap64le(((const uint64_t *)&hash)[1]), difficulty, low, high);
bool carry = cadd(cur, low);
cur = high;
mul(swap64le(((const uint64_t *)&hash)[2]), difficulty, low, high);
carry = cadc(cur, low, carry);
carry = cadc(high, top, carry);
return !carry;
}
#if defined(_MSC_VER)
#ifdef max
#undef max
@ -143,48 +127,6 @@ namespace currency {
}
}
difficulty_type next_difficulty_old(vector<uint64_t> timestamps, vector<difficulty_type> cumulative_difficulties, size_t target_seconds) {
//cutoff DIFFICULTY_LAG
if (timestamps.size() > DIFFICULTY_WINDOW)
{
timestamps.resize(DIFFICULTY_WINDOW);
cumulative_difficulties.resize(DIFFICULTY_WINDOW);
}
size_t length = timestamps.size();
assert(length == cumulative_difficulties.size());
if (length <= 1) {
return DIFFICULTY_STARTER;
}
static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small");
assert(length <= DIFFICULTY_WINDOW);
sort(timestamps.begin(), timestamps.end());
size_t cut_begin, cut_end;
static_assert(2 * DIFFICULTY_CUT <= DIFFICULTY_WINDOW - 2, "Cut length is too large");
if (length <= DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) {
cut_begin = 0;
cut_end = length;
}
else {
cut_begin = (length - (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) + 1) / 2;
cut_end = cut_begin + (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT);
}
assert(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length);
uint64_t time_span = timestamps[cut_end - 1] - timestamps[cut_begin];
if (time_span == 0) {
time_span = 1;
}
difficulty_type total_work = cumulative_difficulties[cut_end - 1] - cumulative_difficulties[cut_begin];
assert(total_work > 0);
uint64_t low, high;
mul(total_work, target_seconds, low, high);
if (high != 0 || low + time_span - 1 < low) {
return 0;
}
return (low + time_span - 1) / time_span;
}
void get_cut_location_from_len(size_t length, size_t& cut_begin, size_t& cut_end, size_t REDEF_DIFFICULTY_WINDOW, size_t REDEF_DIFFICULTY_CUT_OLD, size_t REDEF_DIFFICULTY_CUT_LAST)
{
if (length <= REDEF_DIFFICULTY_WINDOW)
@ -239,6 +181,7 @@ namespace currency {
wide_difficulty_type next_difficulty(vector<uint64_t>& timestamps, vector<wide_difficulty_type>& cumulative_difficulties, size_t target_seconds)
{
TIME_MEASURE_START_PD(target_calculating_enum_blocks);
// timestamps - first is latest, back - is oldest timestamps
if (timestamps.size() > DIFFICULTY_WINDOW)
{

View file

@ -15,13 +15,9 @@
namespace currency
{
typedef std::uint64_t difficulty_type;
typedef boost::multiprecision::uint128_t wide_difficulty_type;
bool check_hash_old(const crypto::hash &hash, difficulty_type difficulty);
difficulty_type next_difficulty_old(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties);
difficulty_type next_difficulty_old(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
bool check_hash(const crypto::hash &hash, wide_difficulty_type difficulty);
wide_difficulty_type next_difficulty(std::vector<std::uint64_t>& timestamps, std::vector<wide_difficulty_type>& cumulative_difficulties, size_t target_seconds);
uint64_t difficulty_to_boundary(wide_difficulty_type difficulty);

View file

@ -245,6 +245,7 @@
"FORM_ERRORS": {
"ADDRESS_REQUIRED": "Address is required.",
"ADDRESS_NOT_VALID": "Address not valid.",
"ALIAS_NOT_VALID": "Alias not valid.",
"AMOUNT_REQUIRED": "Amount is required.",
"AMOUNT_ZERO": "Amount is zero.",
"FEE_REQUIRED": "Fee is required.",
@ -439,17 +440,28 @@
"TITLE_PENDING": "Pending",
"TITLE_TOTAL": "Total",
"TITLE_PERIOD": "Time period:",
"DAY": "1 day",
"WEEK": "1 week",
"MONTH": "1 month",
"YEAR": "1 year",
"ALL": "All",
"PERIOD": {
"WEEK1": "1 week",
"WEEK2": "2 week",
"MONTH1": "1 month",
"MONTH3": "3 month",
"MONTH6": "6 month",
"YEAR": "1 year",
"ALL": "All"
},
"TITLE_GROUP": "Group:",
"GROUP": {
"DAY": "day",
"WEEK": "week",
"MONTH": "month"
},
"SWITCH": {
"ON": "ON",
"OFF": "OFF"
}
},
"ERRORS": {
"NO_MONEY": "Not enough money",
"NOT_ENOUGH_MONEY": "Insufficient funds in account",
"CORE_BUSY": "Internal error (core is busy)",
"DAEMON_BUSY": "Internal error: deamon is busy",

View file

@ -33,6 +33,13 @@ button {
background-color: themed(disabledButtonHoverColor);
}
}
&:focus {
@include themify($themes) {
background-color: themed(disabledButtonFocusColor);
}
}
}
&.blue-button:not(:disabled) {
@ -54,6 +61,13 @@ button {
background-color: themed(blueButtonHoverColor);
}
}
&:focus {
@include themify($themes) {
background-color: themed(blueButtonFocusColor);
}
}
}
&.green-button:not(:disabled) {
@ -69,6 +83,13 @@ button {
background-color: themed(greenButtonHoverColor);
}
}
&:focus {
@include themify($themes) {
background-color: themed(greenButtonFocusColor);
}
}
}
&.turquoise-button:not(:disabled) {
@ -84,6 +105,13 @@ button {
background-color: themed(turquoiseButtonHoverColor);
}
}
&:focus {
@include themify($themes) {
background-color: themed(turquoiseButtonFocusColor);
}
}
}
&.transparent-button {

View file

@ -13,26 +13,31 @@ $themes: (
greenTextColor: #5cda9d,
redTextColor: #fe5252,
blueButtonBackgroundColor: #4db1ff,
blueButtonHoverColor: #60b9ff,
disabledButtonBackgroundColor: #90a4ae,
disabledButtonHoverColor: #9bb0ba,
blueButtonHoverColor: #82d7ff,
blueButtonFocusColor: #59b5fd,
disabledButtonBackgroundColor: #9cadb7,
disabledButtonHoverColor: #b7d1e0,
disabledButtonFocusColor: #a7b9c2,
greenButtonBackgroundColor: #5cda9d,
greenButtonHoverColor: #5ce2a1,
greenButtonHoverColor: #8dfcc6,
greenButtonFocusColor: #62e0b2,
turquoiseButtonBackgroundColor: #4dd0e1,
turquoiseButtonHoverColor: #52d9ea,
turquoiseButtonHoverColor: #87f4f5,
turquoiseButtonFocusColor: #42d5e8,
transparentButtonBorderColor: #2b3644,
inputBackgroundColor: #171e27,
selectHoverColor: rgba(58, 72, 90, 0.5),
selectHoverColor: rgba(58, 69, 85, 0.5),
selectSelectedColor: rgba(43, 54, 68, 0.5),
switchBackgroundColor: #000000,
accountBackgroundColor: rgba(43, 54, 68, 0.5),
accountHoverBackgroundColor: rgba(58, 72, 90, 0.5),
accountHoverBackgroundColor: rgba(58, 69, 85, 0.5),
accountMainTextColor: #e0e0e0,
accountOptionalTextColor: #556576,
accountIndicatorTextColor: #111921,
accountSwitchBackgroundColor: #000000,
accountIndicatorBackgroundColor: #4db1ff,
tabInactiveBackgroundColor: rgba(23, 31, 39, 0.5),
tabHoverBackgroundColor: rgba(58, 69, 85, 0.5),
tableBackgroundColor: #18202a,
messageMyBackgroundColor: #2a3544,
messageBuddyBackgroundColor: #18202a,
@ -47,7 +52,7 @@ $themes: (
),
gray: (
bodyBackgroundColor: #101417,
sidebarBackgroundColor: rgba(23, 25, 27, 0.5),
sidebarBackgroundColor: rgba(28, 30, 33, 0.5),
sidebarBorderColor: #2e3337,
onlineColor: #47cf8d,
offlineColor: #ff5252,
@ -59,26 +64,31 @@ $themes: (
greenTextColor: #47cf8d,
redTextColor: #fe5252,
blueButtonBackgroundColor: #42a5f5,
blueButtonHoverColor: #4dafff,
blueButtonHoverColor: #86d6ff,
blueButtonFocusColor: #5fb6fc,
disabledButtonBackgroundColor: #79848f,
disabledButtonHoverColor: #85909b,
disabledButtonHoverColor: #a1aebb,
disabledButtonFocusColor: #8a959f,
greenButtonBackgroundColor: #47cf8d,
greenButtonHoverColor: #49d993,
greenButtonHoverColor: #7bf6c6,
greenButtonFocusColor: #5cdc9e,
turquoiseButtonBackgroundColor: #3ec5d7,
turquoiseButtonHoverColor: #43cee0,
turquoiseButtonHoverColor: #72edfe,
turquoiseButtonFocusColor: #50d0e1,
transparentButtonBorderColor: #2f3438,
inputBackgroundColor: #292d31,
selectHoverColor: rgba(70, 76, 81, 0.5),
selectHoverColor: rgba(58, 62, 66, 0.5),
selectSelectedColor: rgba(37, 40, 43, 0.5),
switchBackgroundColor: #000000,
accountBackgroundColor: rgba(37, 40, 43, 0.5),
accountHoverBackgroundColor: rgba(70, 76, 81, 0.5),
accountHoverBackgroundColor: rgba(58, 62, 66, 0.5),
accountMainTextColor: #e0e0e0,
accountOptionalTextColor: #565c62,
accountIndicatorTextColor: #1a1a1a,
accountSwitchBackgroundColor: #000000,
accountIndicatorBackgroundColor: #42a5f5,
tabInactiveBackgroundColor: rgba(23, 25, 27, 0.5),
tabInactiveBackgroundColor: rgba(28, 30, 33, 0.5),
tabHoverBackgroundColor: rgba(58, 62, 66, 0.5),
tableBackgroundColor: #25292d,
messageMyBackgroundColor: #30363c,
messageBuddyBackgroundColor: #25292d,
@ -105,13 +115,17 @@ $themes: (
greenTextColor: #46c172,
redTextColor: #ff5252,
blueButtonBackgroundColor: #2c95f1,
blueButtonHoverColor: #379ffa,
blueButtonHoverColor: #5cb3ff,
blueButtonFocusColor: #379ffa,
disabledButtonBackgroundColor: #90a4ae,
disabledButtonHoverColor: #9baeb7,
disabledButtonHoverColor: #aebec6,
disabledButtonFocusColor: #a7b9c2,
greenButtonBackgroundColor: #46c172,
greenButtonHoverColor: #46ca75,
greenButtonHoverColor: #5ad586,
greenButtonFocusColor: #53c77c,
turquoiseButtonBackgroundColor: #26b6c7,
turquoiseButtonHoverColor: #2bbdcf,
turquoiseButtonHoverColor: #52cbd9,
turquoiseButtonFocusColor: #31becf,
transparentButtonBorderColor: #ebebeb,
inputBackgroundColor: #e6e6e6,
selectHoverColor: rgba(240, 240, 240, 0.5),
@ -125,6 +139,7 @@ $themes: (
accountSwitchBackgroundColor: #ffffff,
accountIndicatorBackgroundColor: #ffffff,
tabInactiveBackgroundColor: rgba(224, 224, 224, 0.5),
tabHoverBackgroundColor: #ffffff,
tableBackgroundColor: #ffffff,
messageMyBackgroundColor: #fff,
messageBuddyBackgroundColor: #ededed,

View file

@ -76,6 +76,13 @@ app-wallet {
background-color: themed(contentBackgroundColor);
}
}
&:hover:not(.active) {
@include themify($themes) {
background-color: themed(tabHoverBackgroundColor);
}
}
}
}
@ -92,6 +99,24 @@ app-send {
.form-send {
.input-block-address {
.address-dropdown {
@include themify($themes) {
background-color: themed(inputBackgroundColor);
color: themed(mainTextColor);
}
div:hover {
@include themify($themes) {
background-color: themed(selectHoverColor);
}
}
}
}
.send-select {
@include themify($themes) {
@ -178,7 +203,7 @@ app-history {
}
}
.status.send {
.status.send {
.icon {
background-color: #ff5252;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -79,7 +79,7 @@ export class Wallet {
item.sortFee = new BigNumber(0);
} else if ((item.hasOwnProperty('contract') && (item.contract[0].state === 3 || item.contract[0].state === 6 || item.contract[0].state === 601) && !item.contract[0].is_a)) {
item.sortFee = item.fee.negated();
item.sortAmount = item.amount.negated();
item.sortAmount = item.amount;
} else {
if (!item.is_income) {
item.sortFee = item.fee.negated();

View file

@ -60,7 +60,7 @@ export class BackendService {
'currency': this.variablesService.defaultCurrency
});
} else {
error_translate = 'INFORMER.NO_MONEY';
error_translate = 'ERRORS.NO_MONEY';
}
break;
case 'INTERNAL_ERROR:not enough outputs to mix':

View file

@ -521,6 +521,9 @@ export class AppComponent implements OnInit, OnDestroy {
getAliases() {
this.backend.getAllAliases((status, data, error) => {
console.warn(error);
if (error === 'CORE_BUSY') {
window.setTimeout(() => {
this.getAliases();

View file

@ -62,8 +62,7 @@ export class RestoreWalletComponent implements OnInit {
saveWallet() {
if (this.restoreForm.valid && this.restoreForm.get('name').value.length <= this.variablesService.maxWalletNameLength) {
this.backend.isValidRestoreWalletText(this.restoreForm.get('key').value, (valid_status, valid_data) => {
if (valid_data === 'FALSE') {
if (valid_data !== 'TRUE') {
this.ngZone.run(() => {
this.restoreForm.get('key').setErrors({key_not_valid: true});
});

View file

@ -1,8 +1,14 @@
<form class="form-send" [formGroup]="sendForm" (ngSubmit)="onSend()">
<div class="input-block">
<div class="input-block input-block-address">
<label for="send-address">{{ 'SEND.ADDRESS' | translate }}</label>
<input type="text" id="send-address" formControlName="address" (contextmenu)="variablesService.onContextMenu($event)">
<input type="text" id="send-address" formControlName="address" (mousedown)="addressMouseDown($event)" (contextmenu)="variablesService.onContextMenu($event)">
<div class="address-dropdown scrolled-content" *ngIf="isOpen">
<div *ngFor="let item of localAliases" (click)="setAlias(item.name)">{{item.name}}</div>
</div>
<div class="error-block" *ngIf="sendForm.controls['address'].invalid && (sendForm.controls['address'].dirty || sendForm.controls['address'].touched)">
<div *ngIf="sendForm.controls['address'].errors['required']">
{{ 'SEND.FORM_ERRORS.ADDRESS_REQUIRED' | translate }}
@ -10,6 +16,9 @@
<div *ngIf="sendForm.controls['address'].errors['address_not_valid']">
{{ 'SEND.FORM_ERRORS.ADDRESS_NOT_VALID' | translate }}
</div>
<div *ngIf="sendForm.controls['address'].errors['alias_not_valid']">
{{ 'SEND.FORM_ERRORS.ALIAS_NOT_VALID' | translate }}
</div>
</div>
</div>

View file

@ -4,6 +4,23 @@
.form-send {
.input-block-address {
position: relative;
.address-dropdown {
position: absolute;
top: 6.5rem;
max-height: 10rem;
overflow: auto;
width: 100%;
div {
font-size: 1.4rem;
padding: 1rem;
}
}
}
.input-blocks-row {
display: flex;

View file

@ -1,4 +1,4 @@
import {Component, OnInit, OnDestroy, NgZone} from '@angular/core';
import {Component, OnInit, OnDestroy, NgZone, HostListener} from '@angular/core';
import {FormGroup, FormControl, Validators} from '@angular/forms';
import {ActivatedRoute} from '@angular/router';
import {BackendService} from '../_helpers/services/backend.service';
@ -13,26 +13,57 @@ import {BigNumber} from 'bignumber.js';
})
export class SendComponent implements OnInit, OnDestroy {
isOpen = false;
localAliases = [];
currentWalletId = null;
parentRouting;
sendForm = new FormGroup({
address: new FormControl('', [Validators.required, (g: FormControl) => {
this.localAliases = [];
if (g.value) {
this.backend.validateAddress(g.value, (valid_status) => {
this.ngZone.run(() => {
if (valid_status === false) {
g.setErrors(Object.assign({'address_not_valid': true}, g.errors) );
} else {
if (g.hasError('address_not_valid')) {
delete g.errors['address_not_valid'];
if (Object.keys(g.errors).length === 0) {
g.setErrors(null);
if (g.value.indexOf('@') !== 0) {
this.isOpen = false;
this.backend.validateAddress(g.value, (valid_status) => {
this.ngZone.run(() => {
if (valid_status === false) {
g.setErrors(Object.assign({'address_not_valid': true}, g.errors));
} else {
if (g.hasError('address_not_valid')) {
delete g.errors['address_not_valid'];
if (Object.keys(g.errors).length === 0) {
g.setErrors(null);
}
}
}
}
});
});
});
return (g.hasError('address_not_valid')) ? {'address_not_valid': true} : null;
return (g.hasError('address_not_valid')) ? {'address_not_valid': true} : null;
} else {
this.isOpen = true;
this.localAliases = this.variablesService.aliases.filter((item) => {
return item.name.indexOf(g.value) > -1;
});
if (!(/^@?[a-z0-9\.\-]{6,25}$/.test(g.value))) {
g.setErrors(Object.assign({'alias_not_valid': true}, g.errors));
} else {
this.backend.getAliasByName(g.value.replace('@', ''), (alias_status) => {
this.ngZone.run(() => {
if (alias_status) {
if (g.hasError('alias_not_valid')) {
delete g.errors['alias_not_valid'];
if (Object.keys(g.errors).length === 0) {
g.setErrors(null);
}
}
} else {
g.setErrors(Object.assign({'alias_not_valid': true}, g.errors));
}
});
});
}
return (g.hasError('alias_not_valid')) ? {'alias_not_valid': true} : null;
}
}
return null;
}]),
@ -56,10 +87,29 @@ export class SendComponent implements OnInit, OnDestroy {
constructor(
private route: ActivatedRoute,
private backend: BackendService,
private variablesService: VariablesService,
public variablesService: VariablesService,
private modalService: ModalService,
private ngZone: NgZone
) {}
) {
}
addressMouseDown(e) {
if (e['button'] === 0 && this.sendForm.get('address').value && this.sendForm.get('address').value.indexOf('@') === 0) {
this.isOpen = true;
}
}
setAlias(alias) {
this.sendForm.get('address').setValue(alias);
}
@HostListener('document:click', ['$event.target'])
public onClick(targetElement) {
if (targetElement.id !== 'send-address' && this.isOpen) {
this.isOpen = false;
}
}
ngOnInit() {
this.parentRouting = this.route.parent.params.subscribe(params => {
@ -76,28 +126,55 @@ export class SendComponent implements OnInit, OnDestroy {
onSend() {
if (this.sendForm.valid) {
this.backend.validateAddress(this.sendForm.get('address').value, (valid_status) => {
if (valid_status === false) {
this.ngZone.run(() => {
this.sendForm.get('address').setErrors({address_not_valid: true});
});
} else {
this.backend.sendMoney(
this.currentWalletId,
this.sendForm.get('address').value,
this.sendForm.get('amount').value,
this.sendForm.get('fee').value,
this.sendForm.get('mixin').value,
this.sendForm.get('comment').value,
(send_status, send_data) => {
if (send_status) {
this.modalService.prepareModal('success', 'SEND.SUCCESS_SENT');
this.variablesService.currentWallet.send_data = {address: null, amount: null, comment: null, mixin: null, fee: null};
this.sendForm.reset({address: null, amount: null, comment: null, mixin: 0, fee: this.variablesService.default_fee});
}
if (this.sendForm.get('address').value.indexOf('@') !== 0) {
this.backend.validateAddress(this.sendForm.get('address').value, (valid_status) => {
if (valid_status === false) {
this.ngZone.run(() => {
this.sendForm.get('address').setErrors({'address_not_valid': true});
});
}
});
} else {
this.backend.sendMoney(
this.currentWalletId,
this.sendForm.get('address').value,
this.sendForm.get('amount').value,
this.sendForm.get('fee').value,
this.sendForm.get('mixin').value,
this.sendForm.get('comment').value,
(send_status) => {
if (send_status) {
this.modalService.prepareModal('success', 'SEND.SUCCESS_SENT');
this.variablesService.currentWallet.send_data = {address: null, amount: null, comment: null, mixin: null, fee: null};
this.sendForm.reset({address: null, amount: null, comment: null, mixin: 0, fee: this.variablesService.default_fee});
}
});
}
});
} else {
this.backend.getAliasByName(this.sendForm.get('address').value.replace('@', ''), (alias_status, alias_data) => {
this.ngZone.run(() => {
if (alias_status === false) {
this.ngZone.run(() => {
this.sendForm.get('address').setErrors({'alias_not_valid': true});
});
} else {
this.backend.sendMoney(
this.currentWalletId,
alias_data.address, // this.sendForm.get('address').value,
this.sendForm.get('amount').value,
this.sendForm.get('fee').value,
this.sendForm.get('mixin').value,
this.sendForm.get('comment').value,
(send_status) => {
if (send_status) {
this.modalService.prepareModal('success', 'SEND.SUCCESS_SENT');
this.variablesService.currentWallet.send_data = {address: null, amount: null, comment: null, mixin: null, fee: null};
this.sendForm.reset({address: null, amount: null, comment: null, mixin: 0, fee: this.variablesService.default_fee});
}
});
}
});
});
}
}
}
@ -113,7 +190,7 @@ export class SendComponent implements OnInit, OnDestroy {
comment: this.sendForm.get('comment').value,
mixin: this.sendForm.get('mixin').value,
fee: this.sendForm.get('fee').value
}
};
}
}

View file

@ -16,9 +16,7 @@
</div>
</div>
<div class="selected" *ngIf="selectedDate && selectedDate.date">
<span *ngIf="currentPeriod === '1 day'">{{selectedDate.date | date : 'HH:00 - HH:59, MMM. EEEE, dd, yyyy'}}</span>
<span *ngIf="currentPeriod === 'All'">{{selectedDate.date | date : 'HH:mm, MMM. EEEE, dd, yyyy'}}</span>
<span *ngIf="!(currentPeriod === '1 day' || currentPeriod === 'All')">{{selectedDate.date | date : 'MMM. EEEE, dd, yyyy'}}</span>
<span>{{selectedDate.date | date : 'MMM. EEEE, dd, yyyy'}}</span>
<span>{{selectedDate.amount}} {{variablesService.defaultCurrency}}</span>
</div>
</div>
@ -36,4 +34,13 @@
<button type="button" [class.active]="period.active" (click)="changePeriod(period)">{{period.title}}</button>
</ng-container>
</div>
<div class="title">
{{ 'STAKING.TITLE_GROUP' | translate }}
</div>
<div class="options">
<ng-container *ngFor="let group of groups">
<button type="button" [class.active]="group.active" (click)="changeGroup(group)">{{group.title}}</button>
</ng-container>
</div>
</div>

View file

@ -64,7 +64,11 @@
.title {
font-size: 1.3rem;
width: 9rem;
padding: 0 1rem;
&:first-child{
padding-left: 0;
}
}
.options {

View file

@ -20,32 +20,60 @@ export class StakingComponent implements OnInit, OnDestroy {
periods = [
{
title: this.translate.instant('STAKING.DAY'),
key: '1 day',
active: false
},
{
title: this.translate.instant('STAKING.WEEK'),
title: this.translate.instant('STAKING.PERIOD.WEEK1'),
key: '1 week',
active: false
},
{
title: this.translate.instant('STAKING.MONTH'),
title: this.translate.instant('STAKING.PERIOD.WEEK2'),
key: '2 week',
active: false
},
{
title: this.translate.instant('STAKING.PERIOD.MONTH1'),
key: '1 month',
active: false
},
{
title: this.translate.instant('STAKING.YEAR'),
title: this.translate.instant('STAKING.PERIOD.MONTH3'),
key: '3 month',
active: false
},
{
title: this.translate.instant('STAKING.PERIOD.MONTH6'),
key: '6 month',
active: false
},
{
title: this.translate.instant('STAKING.PERIOD.YEAR'),
key: '1 year',
active: false
},
{
title: this.translate.instant('STAKING.ALL'),
title: this.translate.instant('STAKING.PERIOD.ALL'),
key: 'All',
active: true
}
];
groups = [
{
title: this.translate.instant('STAKING.GROUP.DAY'),
key: 'day',
active: true
},
{
title: this.translate.instant('STAKING.GROUP.WEEK'),
key: 'week',
active: false
},
{
title: this.translate.instant('STAKING.GROUP.MONTH'),
key: 'month',
active: false
}
];
selectedDate = {
date: null,
amount: null
@ -61,8 +89,6 @@ export class StakingComponent implements OnInit, OnDestroy {
total: new BigNumber(0)
};
currentPeriod = 'All';
constructor(
private route: ActivatedRoute,
private variablesService: VariablesService,
@ -73,6 +99,15 @@ export class StakingComponent implements OnInit, OnDestroy {
) {
}
static makeGroupTime(key, date) {
if (key === 'day') {
return date.setHours(0, 0, 0, 0);
} else if (key === 'week') {
return new Date(date.setDate(date.getDate() - date.getDay())).setHours(0, 0, 0, 0);
} else {
return new Date(date.setDate(1)).setHours(0, 0, 0, 0);
}
}
ngOnInit() {
this.parentRouting = this.route.parent.params.subscribe(() => {
@ -112,7 +147,12 @@ export class StakingComponent implements OnInit, OnDestroy {
type: 'line',
backgroundColor: 'transparent',
height: null,
zoomType: null
zoomType: null,
events: {
load: () => {
this.changePeriod();
}
}
},
yAxis: {
@ -241,39 +281,31 @@ export class StakingComponent implements OnInit, OnDestroy {
});
}
this.ngZone.run(() => {
this.drawChart(JSON.parse(JSON.stringify(this.originalData)));
this.drawChart([]);
});
});
}
}
changePeriod(period) {
this.periods.forEach((p) => {
p.active = false;
});
period.active = true;
this.currentPeriod = period.key;
changePeriod(period?) {
if (period) {
this.periods.forEach((p) => {
p.active = false;
});
period.active = true;
} else {
period = this.periods.find((p) => p.active);
}
const d = new Date();
let min = null;
const newData = [];
if (period.key === '1 day') {
const group = this.groups.find((g) => g.active);
if (period.key === '1 week') {
this.originalData.forEach((item) => {
const time = (new Date(item[0])).setUTCMinutes(0, 0, 0);
const find = newData.find(itemNew => itemNew[0] === time);
if (find) {
find[1] = new BigNumber(find[1]).plus(item[1]).toNumber();
} else {
newData.push([time, item[1]]);
}
});
this.chart.ref.series[0].setData(newData, true);
min = Date.UTC(d.getFullYear(), d.getMonth(), d.getDate() - 1, 0, 0, 0, 0);
} else if (period.key === '1 week') {
this.originalData.forEach((item) => {
const time = (new Date(item[0])).setUTCHours(0, 0, 0, 0);
const time = StakingComponent.makeGroupTime(group.key, new Date(item[0]));
const find = newData.find(itemNew => itemNew[0] === time);
if (find) {
find[1] = new BigNumber(find[1]).plus(item[1]).toNumber();
@ -283,9 +315,21 @@ export class StakingComponent implements OnInit, OnDestroy {
});
this.chart.ref.series[0].setData(newData, true);
min = Date.UTC(d.getFullYear(), d.getMonth(), d.getDate() - 7, 0, 0, 0, 0);
} else if (period.key === '2 week') {
this.originalData.forEach((item) => {
const time = StakingComponent.makeGroupTime(group.key, new Date(item[0]));
const find = newData.find(itemNew => itemNew[0] === time);
if (find) {
find[1] = new BigNumber(find[1]).plus(item[1]).toNumber();
} else {
newData.push([time, item[1]]);
}
});
this.chart.ref.series[0].setData(newData, true);
min = Date.UTC(d.getFullYear(), d.getMonth(), d.getDate() - 14, 0, 0, 0, 0);
} else if (period.key === '1 month') {
this.originalData.forEach((item) => {
const time = (new Date(item[0])).setUTCHours(0, 0, 0, 0);
const time = StakingComponent.makeGroupTime(group.key, new Date(item[0]));
const find = newData.find(itemNew => itemNew[0] === time);
if (find) {
find[1] = new BigNumber(find[1]).plus(item[1]).toNumber();
@ -295,9 +339,33 @@ export class StakingComponent implements OnInit, OnDestroy {
});
this.chart.ref.series[0].setData(newData, true);
min = Date.UTC(d.getFullYear(), d.getMonth() - 1, d.getDate(), 0, 0, 0, 0);
} else if (period.key === '3 month') {
this.originalData.forEach((item) => {
const time = StakingComponent.makeGroupTime(group.key, new Date(item[0]));
const find = newData.find(itemNew => itemNew[0] === time);
if (find) {
find[1] = new BigNumber(find[1]).plus(item[1]).toNumber();
} else {
newData.push([time, item[1]]);
}
});
this.chart.ref.series[0].setData(newData, true);
min = Date.UTC(d.getFullYear(), d.getMonth() - 3, d.getDate(), 0, 0, 0, 0);
} else if (period.key === '6 month') {
this.originalData.forEach((item) => {
const time = StakingComponent.makeGroupTime(group.key, new Date(item[0]));
const find = newData.find(itemNew => itemNew[0] === time);
if (find) {
find[1] = new BigNumber(find[1]).plus(item[1]).toNumber();
} else {
newData.push([time, item[1]]);
}
});
this.chart.ref.series[0].setData(newData, true);
min = Date.UTC(d.getFullYear(), d.getMonth() - 6, d.getDate(), 0, 0, 0, 0);
} else if (period.key === '1 year') {
this.originalData.forEach((item) => {
const time = (new Date(item[0])).setUTCHours(0, 0, 0, 0);
const time = StakingComponent.makeGroupTime(group.key, new Date(item[0]));
const find = newData.find(itemNew => itemNew[0] === time);
if (find) {
find[1] = new BigNumber(find[1]).plus(item[1]).toNumber();
@ -308,12 +376,28 @@ export class StakingComponent implements OnInit, OnDestroy {
this.chart.ref.series[0].setData(newData, true);
min = Date.UTC(d.getFullYear() - 1, d.getMonth(), d.getDate(), 0, 0, 0, 0);
} else {
this.chart.ref.series[0].setData(this.originalData, true);
this.originalData.forEach((item) => {
const time = StakingComponent.makeGroupTime(group.key, new Date(item[0]));
const find = newData.find(itemNew => itemNew[0] === time);
if (find) {
find[1] = new BigNumber(find[1]).plus(item[1]).toNumber();
} else {
newData.push([time, item[1]]);
}
});
this.chart.ref.series[0].setData(newData, true);
}
this.chart.ref.xAxis[0].setExtremes(min, null);
}
changeGroup(group) {
this.groups.forEach((g) => {
g.active = false;
});
group.active = true;
this.changePeriod();
}
ngOnDestroy() {
this.parentRouting.unsubscribe();

View file

@ -245,6 +245,7 @@
"FORM_ERRORS": {
"ADDRESS_REQUIRED": "Address is required.",
"ADDRESS_NOT_VALID": "Address not valid.",
"ALIAS_NOT_VALID": "Alias not valid.",
"AMOUNT_REQUIRED": "Amount is required.",
"AMOUNT_ZERO": "Amount is zero.",
"FEE_REQUIRED": "Fee is required.",
@ -439,17 +440,28 @@
"TITLE_PENDING": "Pending",
"TITLE_TOTAL": "Total",
"TITLE_PERIOD": "Time period:",
"DAY": "1 day",
"WEEK": "1 week",
"MONTH": "1 month",
"YEAR": "1 year",
"ALL": "All",
"PERIOD": {
"WEEK1": "1 week",
"WEEK2": "2 week",
"MONTH1": "1 month",
"MONTH3": "3 month",
"MONTH6": "6 month",
"YEAR": "1 year",
"ALL": "All"
},
"TITLE_GROUP": "Group:",
"GROUP": {
"DAY": "day",
"WEEK": "week",
"MONTH": "month"
},
"SWITCH": {
"ON": "ON",
"OFF": "OFF"
}
},
"ERRORS": {
"NO_MONEY": "Not enough money",
"NOT_ENOUGH_MONEY": "Insufficient funds in account",
"CORE_BUSY": "Internal error (core is busy)",
"DAEMON_BUSY": "Internal error: deamon is busy",

View file

@ -33,6 +33,13 @@ button {
background-color: themed(disabledButtonHoverColor);
}
}
&:focus {
@include themify($themes) {
background-color: themed(disabledButtonFocusColor);
}
}
}
&.blue-button:not(:disabled) {
@ -54,6 +61,13 @@ button {
background-color: themed(blueButtonHoverColor);
}
}
&:focus {
@include themify($themes) {
background-color: themed(blueButtonFocusColor);
}
}
}
&.green-button:not(:disabled) {
@ -69,6 +83,13 @@ button {
background-color: themed(greenButtonHoverColor);
}
}
&:focus {
@include themify($themes) {
background-color: themed(greenButtonFocusColor);
}
}
}
&.turquoise-button:not(:disabled) {
@ -84,6 +105,13 @@ button {
background-color: themed(turquoiseButtonHoverColor);
}
}
&:focus {
@include themify($themes) {
background-color: themed(turquoiseButtonFocusColor);
}
}
}
&.transparent-button {

View file

@ -13,26 +13,31 @@ $themes: (
greenTextColor: #5cda9d,
redTextColor: #fe5252,
blueButtonBackgroundColor: #4db1ff,
blueButtonHoverColor: #60b9ff,
disabledButtonBackgroundColor: #90a4ae,
disabledButtonHoverColor: #9bb0ba,
blueButtonHoverColor: #82d7ff,
blueButtonFocusColor: #59b5fd,
disabledButtonBackgroundColor: #9cadb7,
disabledButtonHoverColor: #b7d1e0,
disabledButtonFocusColor: #a7b9c2,
greenButtonBackgroundColor: #5cda9d,
greenButtonHoverColor: #5ce2a1,
greenButtonHoverColor: #8dfcc6,
greenButtonFocusColor: #62e0b2,
turquoiseButtonBackgroundColor: #4dd0e1,
turquoiseButtonHoverColor: #52d9ea,
turquoiseButtonHoverColor: #87f4f5,
turquoiseButtonFocusColor: #42d5e8,
transparentButtonBorderColor: #2b3644,
inputBackgroundColor: #171e27,
selectHoverColor: rgba(58, 72, 90, 0.5),
selectHoverColor: rgba(58, 69, 85, 0.5),
selectSelectedColor: rgba(43, 54, 68, 0.5),
switchBackgroundColor: #000000,
accountBackgroundColor: rgba(43, 54, 68, 0.5),
accountHoverBackgroundColor: rgba(58, 72, 90, 0.5),
accountHoverBackgroundColor: rgba(58, 69, 85, 0.5),
accountMainTextColor: #e0e0e0,
accountOptionalTextColor: #556576,
accountIndicatorTextColor: #111921,
accountSwitchBackgroundColor: #000000,
accountIndicatorBackgroundColor: #4db1ff,
tabInactiveBackgroundColor: rgba(23, 31, 39, 0.5),
tabHoverBackgroundColor: rgba(58, 69, 85, 0.5),
tableBackgroundColor: #18202a,
messageMyBackgroundColor: #2a3544,
messageBuddyBackgroundColor: #18202a,
@ -47,7 +52,7 @@ $themes: (
),
gray: (
bodyBackgroundColor: #101417,
sidebarBackgroundColor: rgba(23, 25, 27, 0.5),
sidebarBackgroundColor: rgba(28, 30, 33, 0.5),
sidebarBorderColor: #2e3337,
onlineColor: #47cf8d,
offlineColor: #ff5252,
@ -59,26 +64,31 @@ $themes: (
greenTextColor: #47cf8d,
redTextColor: #fe5252,
blueButtonBackgroundColor: #42a5f5,
blueButtonHoverColor: #4dafff,
blueButtonHoverColor: #86d6ff,
blueButtonFocusColor: #5fb6fc,
disabledButtonBackgroundColor: #79848f,
disabledButtonHoverColor: #85909b,
disabledButtonHoverColor: #a1aebb,
disabledButtonFocusColor: #8a959f,
greenButtonBackgroundColor: #47cf8d,
greenButtonHoverColor: #49d993,
greenButtonHoverColor: #7bf6c6,
greenButtonFocusColor: #5cdc9e,
turquoiseButtonBackgroundColor: #3ec5d7,
turquoiseButtonHoverColor: #43cee0,
turquoiseButtonHoverColor: #72edfe,
turquoiseButtonFocusColor: #50d0e1,
transparentButtonBorderColor: #2f3438,
inputBackgroundColor: #292d31,
selectHoverColor: rgba(70, 76, 81, 0.5),
selectHoverColor: rgba(58, 62, 66, 0.5),
selectSelectedColor: rgba(37, 40, 43, 0.5),
switchBackgroundColor: #000000,
accountBackgroundColor: rgba(37, 40, 43, 0.5),
accountHoverBackgroundColor: rgba(70, 76, 81, 0.5),
accountHoverBackgroundColor: rgba(58, 62, 66, 0.5),
accountMainTextColor: #e0e0e0,
accountOptionalTextColor: #565c62,
accountIndicatorTextColor: #1a1a1a,
accountSwitchBackgroundColor: #000000,
accountIndicatorBackgroundColor: #42a5f5,
tabInactiveBackgroundColor: rgba(23, 25, 27, 0.5),
tabInactiveBackgroundColor: rgba(28, 30, 33, 0.5),
tabHoverBackgroundColor: rgba(58, 62, 66, 0.5),
tableBackgroundColor: #25292d,
messageMyBackgroundColor: #30363c,
messageBuddyBackgroundColor: #25292d,
@ -105,13 +115,17 @@ $themes: (
greenTextColor: #46c172,
redTextColor: #ff5252,
blueButtonBackgroundColor: #2c95f1,
blueButtonHoverColor: #379ffa,
blueButtonHoverColor: #5cb3ff,
blueButtonFocusColor: #379ffa,
disabledButtonBackgroundColor: #90a4ae,
disabledButtonHoverColor: #9baeb7,
disabledButtonHoverColor: #aebec6,
disabledButtonFocusColor: #a7b9c2,
greenButtonBackgroundColor: #46c172,
greenButtonHoverColor: #46ca75,
greenButtonHoverColor: #5ad586,
greenButtonFocusColor: #53c77c,
turquoiseButtonBackgroundColor: #26b6c7,
turquoiseButtonHoverColor: #2bbdcf,
turquoiseButtonHoverColor: #52cbd9,
turquoiseButtonFocusColor: #31becf,
transparentButtonBorderColor: #ebebeb,
inputBackgroundColor: #e6e6e6,
selectHoverColor: rgba(240, 240, 240, 0.5),
@ -125,6 +139,7 @@ $themes: (
accountSwitchBackgroundColor: #ffffff,
accountIndicatorBackgroundColor: #ffffff,
tabInactiveBackgroundColor: rgba(224, 224, 224, 0.5),
tabHoverBackgroundColor: #ffffff,
tableBackgroundColor: #ffffff,
messageMyBackgroundColor: #fff,
messageBuddyBackgroundColor: #ededed,

View file

@ -76,6 +76,13 @@ app-wallet {
background-color: themed(contentBackgroundColor);
}
}
&:hover:not(.active) {
@include themify($themes) {
background-color: themed(tabHoverBackgroundColor);
}
}
}
}
@ -92,6 +99,24 @@ app-send {
.form-send {
.input-block-address {
.address-dropdown {
@include themify($themes) {
background-color: themed(inputBackgroundColor);
color: themed(mainTextColor);
}
div:hover {
@include themify($themes) {
background-color: themed(selectHoverColor);
}
}
}
}
.send-select {
@include themify($themes) {
@ -178,7 +203,7 @@ app-history {
}
}
.status.send {
.status.send {
.icon {
background-color: #ff5252;

View file

@ -193,6 +193,8 @@ namespace currency
res.performance_data.etc_stuff_6 = pd.etc_stuff_6.get_avg();
res.performance_data.insert_time_4 = pd.insert_time_4.get_avg();
res.performance_data.raise_block_core_event = pd.raise_block_core_event.get_avg();
res.performance_data.target_calculating_enum_blocks = pd.target_calculating_enum_blocks.get_avg();
res.performance_data.target_calculating_calc = pd.target_calculating_calc.get_avg();
//tx processing zone
res.performance_data.tx_check_inputs_time = pd.tx_check_inputs_time.get_avg();
res.performance_data.tx_add_one_tx_time = pd.tx_add_one_tx_time.get_avg();
@ -891,7 +893,7 @@ namespace currency
response.height = get_block_height(blk);
response.depth = m_core.get_current_blockchain_size() - response.height - 1;
response.hash = string_tools::pod_to_hex(get_block_hash(blk));
response.difficulty = m_core.get_blockchain_storage().block_difficulty(response.height).convert_to<uint64_t>();
response.difficulty = m_core.get_blockchain_storage().block_difficulty(response.height).convert_to<std::string>();
response.reward = get_block_reward(blk);
return true;
}

View file

@ -459,6 +459,8 @@ namespace currency
uint64_t etc_stuff_6;
uint64_t insert_time_4;
uint64_t raise_block_core_event;
uint64_t target_calculating_enum_blocks;
uint64_t target_calculating_calc;
//tx processing zone
uint64_t tx_check_inputs_time;
@ -505,7 +507,8 @@ namespace currency
KV_SERIALIZE(etc_stuff_6)
KV_SERIALIZE(insert_time_4)
KV_SERIALIZE(raise_block_core_event)
KV_SERIALIZE(target_calculating_enum_blocks)
KV_SERIALIZE(target_calculating_calc)
//tx processing zone
KV_SERIALIZE(tx_check_inputs_time)
KV_SERIALIZE(tx_add_one_tx_time)
@ -831,7 +834,7 @@ namespace currency
uint64_t height;
uint64_t depth;
std::string hash;
difficulty_type difficulty;
std::string difficulty;
uint64_t reward;
BEGIN_KV_SERIALIZE_MAP()

View file

@ -34,8 +34,8 @@ target_link_libraries(difficulty-tests currency_core ${CMAKE_THREAD_LIBS_INIT} e
target_link_libraries(functional_tests wallet currency_core crypto common rpc zlibstatic ethash upnpc-static ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
target_link_libraries(hash-tests crypto ethash)
target_link_libraries(hash-target-tests crypto currency_core ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
target_link_libraries(performance_tests currency_core common crypto zlibstatic ethash${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
target_link_libraries(unit_tests wallet currency_core crypto common gtest_main zlibstatic ethash${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
target_link_libraries(performance_tests currency_core common crypto zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
target_link_libraries(unit_tests wallet currency_core crypto common gtest_main zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
target_link_libraries(net_load_tests_clt currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
target_link_libraries(net_load_tests_srv currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})

View file

@ -52,7 +52,7 @@ bool gen_chain_switch_pow_pos::generate(std::vector<test_event_entry>& events) c
for(size_t i = 0; i < CURRENCY_MINED_MONEY_UNLOCK_WINDOW; ++i)
{
block blk = AUTO_VAL_INIT(blk);
uint64_t ts = blk_0r.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN / 3; // to increase main chain difficulty
uint64_t ts = blk_0r.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN / 2; // to increase main chain difficulty
bool r = generator.construct_block_manually(blk, blk_0r, miner_acc,test_generator::bf_timestamp, 0, 0, ts);
CHECK_AND_ASSERT_MES(r, false, "construct_block_manually failed");
events.push_back(blk);

View file

@ -28,7 +28,7 @@ std::atomic<int64_t> test_core_time::m_time_shift;
#define TESTS_DEFAULT_FEE TX_DEFAULT_FEE
static std::atomic<uint64_t> s_generated_money_total(0);
static std::atomic<uint64_t> s_generated_money_total(0); // TODO: consiger changing to boost::multiprecision::uint128_t
static size_t s_wallets_total_count = 10; // total number of wallet that will be randomly used to generate transactions
//static size_t s_althchains_minimum_height = 150; // height at which althchaining is started
static size_t s_tx_generation_minimum_height = 100; // height at which tx generation is started
@ -43,7 +43,7 @@ typedef std::vector<std::shared_ptr<tools::wallet2>> cct_wallets_t;
static const std::vector<currency::extra_v> empty_extra;
static const std::vector<currency::attachment_v> empty_attachment;
bool create_block_template_manually(const currency::block& prev_block, uint64_t already_generated_coins, const std::vector<const currency::transaction*>& txs, const currency::account_public_address& miner_addr, currency::block& result)
bool create_block_template_manually(const currency::block& prev_block, boost::multiprecision::uint128_t already_generated_coins, const std::vector<const currency::transaction*>& txs, const currency::account_public_address& miner_addr, currency::block& result)
{
result.flags = 0;
result.major_version = CURRENT_BLOCK_MAJOR_VERSION;
@ -572,7 +572,7 @@ bool core_concurrency_test(boost::program_options::variables_map& vm, size_t wth
<< replay_time_ms / (events.empty() ? 1 : events.size()) << " ms per event, " << events.size() << " events total", LOG_LEVEL_0);
core_state_after_playback.fill(c);
uint64_t already_generated_coins = 0;
boost::multiprecision::uint128_t already_generated_coins = 0;
{
block_extended_info bei = AUTO_VAL_INIT(bei);
c.get_blockchain_storage().get_block_extended_info_by_hash(c.get_blockchain_storage().get_top_block_id(), bei);
@ -583,7 +583,7 @@ bool core_concurrency_test(boost::program_options::variables_map& vm, size_t wth
if (rthreads > 0)
{
s_generated_money_total = s_generated_money_total / rthreads;
LOG_PRINT("Generated coins: " << print_money(already_generated_coins) << ", counted by readers (with fee): " << print_money(s_generated_money_total), LOG_LEVEL_0);
LOG_PRINT("Generated coins: " << print_money(already_generated_coins) << ", counted by readers (with fee): " << print_money(s_generated_money_total.load()), LOG_LEVEL_0);
}
LOG_PRINT("Writers' stats:", LOG_LEVEL_0);

View file

@ -12,6 +12,7 @@
using namespace epee;
#include "wallet/wallet2.h"
#include "currency_core/blockchain_storage.h"
#include "currency_core/basic_pow_helpers.h"
using std::size_t;
@ -318,11 +319,29 @@ void run_emulation(const std::string& path)
LOG_PRINT_L0("Done");
}
void hash_rate_analysis(const std::string& path);
void run_difficulty_analysis(const std::string& path)
{
//hash_rate_analysis(path);
run_emulation(path);
// currency::block b = AUTO_VAL_INIT(b);
// std::string s("sdsccasc");
// b.miner_tx.extra.push_back(s);
//
// crypto::hash mining_hash = currency::null_hash;
// bool r = string_tools::parse_tpod_from_hex_string("7759031ee0f014fe45476724df268f61c890b4a4637df1489a6c94c0135efbd8", mining_hash);
// uint64_t nonce = 13704307308123612296;
// crypto::hash pow_hash = currency::get_block_longhash(6, mining_hash, nonce);
//
// std::cout << mining_hash << ENDL;
// std::cout << pow_hash << ENDL;
//crypto::hash mining_hash = currency::get_block_header_mining_hash(b);
//crypto::hash id_hash = currency::get_block_hash(b);
hash_rate_analysis(path);
//run_emulation(path);
}

View file

@ -264,7 +264,11 @@ TEST_F(positive_test_connection_to_levin_protocol_handler_calls, handler_initial
TEST_F(positive_test_connection_to_levin_protocol_handler_calls, concurent_handler_initialization_and_destruction_is_correct)
{
const size_t connection_count = 10000;
<<<<<<< HEAD
auto create_and_destroy_connections = [this, connection_count]()
=======
auto create_and_destroy_connections = [&]()
>>>>>>> master
{
std::vector<test_connection_ptr> connections(connection_count);
for (size_t i = 0; i < connection_count; ++i)

View file

@ -128,11 +128,11 @@ TEST(validate_parse_amount_case, validate_parse_amount)
uint64_t res = 0;
bool r = currency::parse_amount(res, "0.0001");
ASSERT_TRUE(r);
ASSERT_EQ(res, 10000);
ASSERT_EQ(res, 100000000);
r = currency::parse_amount(res, "100.0001");
ASSERT_TRUE(r);
ASSERT_EQ(res, 10000010000);
ASSERT_EQ(res, 100000100000000);
r = currency::parse_amount(res, "000.0000");
ASSERT_TRUE(r);
@ -145,11 +145,11 @@ TEST(validate_parse_amount_case, validate_parse_amount)
r = currency::parse_amount(res, " 100.0001 ");
ASSERT_TRUE(r);
ASSERT_EQ(res, 10000010000);
ASSERT_EQ(res, 100000100000000);
r = currency::parse_amount(res, " 100.0000 ");
ASSERT_TRUE(r);
ASSERT_EQ(res, 10000000000);
ASSERT_EQ(res, 100000000000000);
r = currency::parse_amount(res, " 100. 0000 ");
ASSERT_FALSE(r);

View file

@ -3,7 +3,7 @@ curr_path=${BASH_SOURCE%/*}
version_file_path=../src/version.h.in
pushd $curr_path
git pull
git pull --ff-only
if [ $? -ne 0 ]; then
echo "Failed to pull"
popd