forked from lthn/blockchain
Merge branch 'master' into offsig
# Conflicts: # tests/unit_tests/epee_levin_protocol_handler_async.cpp
This commit is contained in:
commit
d51664e5dc
38 changed files with 904 additions and 313 deletions
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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':
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -64,7 +64,11 @@
|
|||
|
||||
.title {
|
||||
font-size: 1.3rem;
|
||||
width: 9rem;
|
||||
padding: 0 1rem;
|
||||
|
||||
&:first-child{
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.options {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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})
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue