1
0
Fork 0
forked from lthn/blockchain

Merge remote-tracking branch 'origin/frontend'

This commit is contained in:
wildkif 2019-04-24 17:40:49 +03:00
commit a609f6b974
69 changed files with 1568 additions and 587 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

@ -316,6 +316,7 @@ DISABLE_VS_WARNINGS(4355)
send_guard.unlock();//manual unlock
LOG_ERROR("send to [" << print_connection_context_short(context) << ", (" << (void*)this << ")] que size is more than ABSTRACT_SERVER_SEND_QUE_MAX_COUNT(" << ABSTRACT_SERVER_SEND_QUE_MAX_COUNT << "), shutting down connection");
close();
shutdown();
return false;
}
@ -351,6 +352,8 @@ DISABLE_VS_WARNINGS(4355)
template<class t_protocol_handler>
bool connection<t_protocol_handler>::shutdown()
{
if (m_was_shutdown)
return true;
// Initiate graceful connection closure.
boost::system::error_code ignored_ec;
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);

View file

@ -116,27 +116,27 @@ inline uint32_t random_math(uint32_t a, uint32_t b, uint32_t selector) noexcept
switch (selector % 11)
{
default:
case 0:
return a * b;
case 1:
return a + b;
case 2:
return mul_hi32(a, b);
return a + b;
case 3:
return std::min(a, b);
return a * b;
case 4:
return rotl32(a, b);
return mul_hi32(a, b);
case 5:
return rotr32(a, b);
return std::min(a, b);
case 6:
return a & b;
return rotl32(a, b);
case 7:
return a | b;
return rotr32(a, b);
case 8:
return a ^ b;
return a & b;
case 9:
return clz32(a) + clz32(b);
return a | b;
case 10:
return a ^ b;
case 0:
return clz32(a) + clz32(b);
case 1:
return popcount32(a) + popcount32(b);
}
}

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

@ -7,7 +7,7 @@
#pragma once
#define CURRENCY_FORMATION_VERSION 79
#define CURRENCY_FORMATION_VERSION 81
#define CURRENCY_MAX_BLOCK_NUMBER 500000000
@ -53,7 +53,7 @@
// #define CURRENCY_FIXED_REWARD_ZONE_REWARD_AMOUNT ((uint64_t)100000000) // should be TX_MINIMUM_FEE * CURRENCY_FIXED_REWARD_ZONE_FEE_MULTIPLIER
// #define CURRENCY_FIXED_REWARD_ZONE_FEE_MULTIPLIER 1000 // reward in minimum fees for a block in the zone
#define CURRENCY_TESTNET_CONST_REWARD 100000000000000
#define CURRENCY_BLOCK_REWARD 1000000000000 // 1.0 coin
#define WALLET_MAX_ALLOWED_OUTPUT_AMOUNT ((uint64_t)0xffffffffffffffffLL)

View file

@ -2377,7 +2377,7 @@ namespace currency
if (!height)
return PREMINE_AMOUNT;
return CURRENCY_TESTNET_CONST_REWARD;
return CURRENCY_BLOCK_REWARD;
}
//-----------------------------------------------------------------------------------------------
bool get_block_reward(bool is_pos, size_t median_size, size_t current_block_size, const boost::multiprecision::uint128_t& already_generated_coins, uint64_t &reward, uint64_t height)

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

@ -8,7 +8,7 @@
namespace currency
{
const genesis_tx_raw_data ggenesis_tx_raw = { {
0xa080800e00000101,0x800326b0b4a0f2fd,0x46f236cb0efcd16c,0x547fbb0ff9468d85,0x1da1229cbceeeddf,0x00509f1127de5f6d,0xb0b4a0f2fda08080,0x19fbc70d41860326,0xb0afa73cfe1209ca,0x0d299d4e62aa2f1f,0x7071d8e322c2ebfc,0xf2fda0808000ed15,0x9e5a660326b0b4a0,0x2928590bf14c0f33,0x3dfd3f48e046a8c2,0xfa969b2fa09ad0ed,0x808000acfcbb24be,0x0326b0b4a0f2fda0,0x682ecad7a79177d8,0xc9e501939827d6ec,0x7f55e8f25beacf76,0xc3a22fd82ddcb367,0xb4f89aecdce08000,0x6aeaf9b0de0326b0,0x631393eedf0fc04d,0x8ed9b961192f541a,0x5088f34df1470474,0x93dc80800011241e,0x30b80307d0ffc2e0,0xdcf3a14a0ac108e5,0xd508a0ec648f342d,0x0c1ac8310dcce994,0x8000346b43733822,0x05c6c5bc97b1a080,0x44663811c2802f03,0x5456a1cc803e5b0c,0x9a7c995f82c5bb18,0xe95939d19b769901,0xbc97b1a0808000e9,0xb0624da20305c6c5,0xe7921e8df615d26f,0x27abce5d4d975bc6,0xecb92e6224ce0952,0xa080800085eb1099,0xb10305c6c5bc97b1,0xea6de475ef2cdaaf,0xa47b3fe828343c89,0x8ec5057c0bf7dd44,0x000f2403abe0ade8,0xc6c5bc97b1a08080,0x60e1a72d445b0305,0x8bb2fc2bfd63e41b,0x7772ae843713073b,0xe1c2db8d00c414ff,0x97b1a0808000b5c2,0xd69ad60305c6c5bc,0x8b0b54a7a541d22c,0x312a3c33f20800c1,0xe401b39ce755f512,0x808000d176bfb84a,0x0305c6c5bc97b1a0,0x7711834fbded84b6,0x1d4dca20946a1b23,0x80bfed89b730469e,0x641a20bd14e5d7cf,0xc5bc97b1a0808000,0xca32ddfd2c0305c6,0xf662200d93c916ca,0x0ca700521b6ece14,0x1a14d2365bb10a8e,0xbd88808000fd386e,0xc6e40304dbfb86ad,0xaba7f00aede6da7a,0xc5a36eac7d327196,0x5237aa32dafc085e,0x11003545013f1ed3,0xbd65d3fbab8aa616,0xb8c69175919e298e,0xe4fe3762fd534801,0xba7de375298d061d,0xf917cbb4170015e4,0x1747ce171e061770,0x05d7177e6b170d69,0x69170e891774ff17,0x17882e17c3621765,0x000a0ec1de17d7e4 },
{ 0x00 } };
0xa080801700000101,0xf30326b0b4a0f2fd,0x46fe96860beb01ea,0x01323293f642c7c6,0x80e8a7730e20c142,0x00cb08b2016bbccc,0xb0b4a0f2fda08080,0xb67d52cae50e0326,0x71bb6e75bf256319,0x76dd703cec5e8f40,0xfca18c41540510b9,0xf2fda080800070f3,0xeea9320326b0b4a0,0xb5d90ea5fe49c4cb,0x3f1e5ca079fe6ebb,0x2f73ac1012e243d0,0x808000887086f29b,0x0326b0b4a0f2fda0,0x44f1a1dfe16379f9,0x50d93954cca94108,0x9ac47bb379e6f074,0xb44bdb69a986211e,0xb4f89aecdce08000,0x88b82d0dc60326b0,0x4e995861a27c03ae,0xdf48c9c97c449f1d,0xdd2ea49c4ecdcbdf,0x93dc80800046f5dc,0xedff0307d0ffc2e0,0x4a8442409d3719b1,0x2e385d03544c8122,0x0c592cfad6e8e900,0x8000ed0b32aa07c6,0x05c6c5bc97b1a080,0xa5d7620e38d8ef03,0x1c68e9cfd35cc1e5,0xbdba8ea5fb49f375,0x7fb77cff80f31c9e,0xbc97b1a080800040,0xd15b16b60305c6c5,0x7af40193ad86f123,0x5ba33fd12279af67,0x0db572d11ea1ad96,0xa080800024fc1fde,0x460305c6c5bc97b1,0x444d02aa28a539b9,0x9846386a58c71f35,0x27fd9af12bd3710a,0x0004b2acf589ce8d,0xc6c5bc97b1a08080,0x610c62c125e80305,0x44217ee86d4ed16f,0x5f27600912875c5f,0x51f2fbfd2b30ff54,0x97b1a08080002698,0x8180fc0305c6c5bc,0xaeb4bfd37d282432,0x10a11a1c799b6165,0x9c69b9b6aac75596,0x8080009c5a6d5e15,0x0305c6c5bc97b1a0,0xbf9f36e03f56393a,0x0a74acb0775f0e02,0x97665a42cb477844,0xff01a0c03c43df12,0xc5bc97b1a0808000,0xd5066341560305c6,0x5aa8c1962a148222,0xf83737ab96d43653,0x4b5007cf8fd4a1e2,0xd2dc808000565d84,0xa6a8030398c7f980,0x32c08d3989aa7f91,0xe4b5de74db34eb45,0xf2bd313bdefdfcba,0x80007e3bb1b21fd2,0x018e8df2b7f0a080,0xb2fe8efdeb17a903,0xe7f89d45d4b05be9,0x96f5300e672fd804,0xbd82737c2ce8c3cf,0xef93bf82808000c2,0x816c799a1f0308f0,0x98bd1487b0e05122,0x044d8ffd583693ba,0x1c954a13f5425015,0xfe848080007c6407,0xcde2510311e1dea6,0x3c62da3d50c8a8ee,0xa3acc1ed75d470b1,0xa479c78eecc2f96c,0x8080005f7388cbcb,0xbd0308f0ef93bf82,0xb5a5cca060105de4,0x92cf66a16d3b4d6b,0x5ca92a654f5a8400,0x00df465ad6e8d895,0x08f0ef93bf828080,0x2ce3338452319303,0xecc7b1c056651998,0xc3696cf2fb2fe9b9,0x69b4edf21f2bdaae,0xafeaa69a808000b8,0x1052e2e6de0301e3,0xa06855ba0d7eaab2,0x344998a33e968f15,0xa8a00006653f7005,0xa69a808000a95440,0x58e0580301e3afea,0xc0524c1a0a1d4b5f,0xad37550b686c838b,0x0eb1ef4a20771a79,0x80800080516862ab,0xa30301e3afeaa69a,0xda2b32dbac7f88cc,0x965536648651d1a2,0xbbe22f6bdc320069,0x00a8ea3fddccf16d,0x03c6dfd4ccb48080,0x9921a91a97490603,0x57ceadcb0611b6de,0xa53cee6b71e61ecb,0x0e56262c5e13302f,0x04ee9ff0161a000a,0xa43f85172baeb3d9,0x782309f5ee0a02f0,0x5d187fedafdfae4f,0x971700150f26e04b,0x17482917b0a717cb,0x1fe617c89e1725b4,0x4017c6e317a97217,0x17a7ca178e6117c1,0xd24717fd3917aa53,0xd217b83c178b9b17,0x17d92517d51c17d4,0xda9d17154f17f6fc },
{ 0x17,0x41,0x0a,0x0e,0x0a,0x00,0x00 } };
}

View file

@ -8,11 +8,12 @@
#include <string>
namespace currency
{
#pragma pack(push, 1)
#pragma pack(push, 1)
struct genesis_tx_raw_data
{
uint64_t const v[86];
uint8_t const r[1];
uint64_t const v[136];
uint8_t const r[7];
};
#pragma pack(pop)
extern const genesis_tx_raw_data ggenesis_tx_raw;

View file

@ -9,25 +9,34 @@
namespace currency
{
const std::string ggenesis_tx_pub_key_str = "a68aabfbd365bd8e299e917591c6b8014853fd6237fee41d068d2975e37dbae4";
const std::string ggenesis_tx_pub_key_str = "f09fee04d9b3ae2b17853fa4f0020aeef50923784faedfafed7f185d4be0260f";
const crypto::public_key ggenesis_tx_pub_key = epee::string_tools::parse_tpod_from_hex_string<crypto::public_key>(ggenesis_tx_pub_key_str);
const genesis_tx_dictionary_entry ggenesis_dict[14] = {
const genesis_tx_dictionary_entry ggenesis_dict[23] = {
{ 898363347618325980ULL,7 },
{ 1234271292339965434ULL,1 },
{ 2785329203593578547ULL,12 },
{ 2912579291078040461ULL,18 },
{ 3515932779881697835ULL,17 },
{ 4955366495399988463ULL,11 },
{ 5233257582118330150ULL,5 },
{ 5511617689742669301ULL,22 },
{ 6436517662239927298ULL,19 },
{ 6604452700210763953ULL,13 },
{ 7200550178847042641ULL,15 },
{ 8712326356392296687ULL,9 },
{ 8863158309745010598ULL,4 },
{ 9048445805125559105ULL,16 },
{ 9527474759752332295ULL,2 },
{ 9647541513390373765ULL,20 },
{ 9921730437908704447ULL,8 },
{ 11109691972771859220ULL,0 },
{ 14297297752337562678ULL,3 },
{ 15636081871140663679ULL,21 },
{ 15951161519112687845ULL,6 },
{ 17146058209502212345ULL,14 },
{ 17472133472787764818ULL,10 }
};
}

View file

@ -24,7 +24,7 @@ namespace currency
}
};
#pragma pack(pop)
extern const genesis_tx_dictionary_entry ggenesis_dict[14];
extern const genesis_tx_dictionary_entry ggenesis_dict[23];
extern const crypto::public_key ggenesis_tx_pub_key;

View file

@ -4,6 +4,7 @@
"SETUP_CONFIRM_PASS": "Confirm the password",
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required.",
@ -83,6 +84,13 @@
"NAME_REQUIRED": "Name is required.",
"NAME_DUPLICATE": "Name is duplicate.",
"MAX_LENGTH": "Maximum name length reached."
},
"MODAL": {
"TITLE": "Type wallet password",
"LABEL": "Password to this wallet",
"OPEN": "Open wallet",
"SKIP": "Skip",
"NOT_FOUND": "Not found"
}
},
"RESTORE_WALLET": {
@ -440,11 +448,21 @@
"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"

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 {
@ -597,6 +625,10 @@ input[type='checkbox'].style-checkbox {
.ng-value-container {
padding: 0;
.ng-input {
top: auto;
}
}
}
@ -752,3 +784,14 @@ app-progress-container {
}
}
}
app-open-wallet-modal {
.modal {
@include themify($themes) {
background: themed(modalBackground);
color: themed(mainTextColor);
}
}
}

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);
}
}
}
}

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

@ -104,11 +104,11 @@ export class ContractStatusMessagesPipe implements PipeTransform {
return state.part1 + (state.part2.length ? '. ' + state.part2 : '');
}
transform(item: any, args?: any): any {
if (item.is_a) {
return this.getStateBuyer(item.state);
transform(state: number, is_a?: boolean): any {
if (is_a) {
return this.getStateBuyer(state);
} else {
return this.getStateSeller(item.state);
return this.getStateSeller(state);
}
}

View file

@ -13,9 +13,27 @@ export class BackendService {
backendObject: any;
backendLoaded = false;
constructor(private translate: TranslateService, private variablesService: VariablesService, private modalService: ModalService, private moneyToIntPipe: MoneyToIntPipe) {}
constructor(
private translate: TranslateService,
private variablesService: VariablesService,
private modalService: ModalService,
private moneyToIntPipe: MoneyToIntPipe
) {
}
private Debug(type, message) {
static bigNumberParser(key, val) {
if (val.constructor.name === 'BigNumber' && ['balance', 'unlocked_balance', 'amount', 'fee', 'b_fee', 'to_pay', 'a_pledge', 'b_pledge', 'coast', 'a'].indexOf(key) === -1) {
return val.toNumber();
}
if (key === 'rcv' || key === 'spn') {
for (let i = 0; i < val.length; i++) {
val[i] = new BigNumber(val[i]);
}
}
return val;
}
static Debug(type, message) {
switch (type) {
case 0:
console.error(message);
@ -112,13 +130,14 @@ export class BackendService {
}
}
break;
case 'NOT_FOUND': if (command !== 'open_wallet' && command !== 'get_alias_info_by_name' && command !== 'get_alias_info_by_address') {
error_translate = this.translate.instant('ERRORS.FILE_NOT_FOUND');
params = JSON.parse(params);
if (params.path) {
error_translate += ': ' + params.path;
case 'NOT_FOUND':
if (command !== 'open_wallet' && command !== 'get_alias_info_by_name' && command !== 'get_alias_info_by_address') {
error_translate = this.translate.instant('ERRORS.FILE_NOT_FOUND');
params = JSON.parse(params);
if (params.path) {
error_translate += ': ' + params.path;
}
}
}
break;
case 'CANCELED':
case '':
@ -142,36 +161,21 @@ export class BackendService {
}
}
private bigNumberParser(key, val) {
if (val.constructor.name === 'BigNumber' && ['balance', 'unlocked_balance', 'amount', 'fee', 'b_fee', 'to_pay', 'a_pledge', 'b_pledge', 'coast', 'a'].indexOf(key) === -1) {
return val.toNumber();
}
if (key === 'rcv' || key === 'spn') {
for (let i = 0; i < val.length; i++) {
val[i] = new BigNumber(val[i]);
}
}
return val;
}
private commandDebug(command, params, result) {
this.Debug(2, '----------------- ' + command + ' -----------------');
BackendService.Debug(2, '----------------- ' + command + ' -----------------');
const debug = {
_send_params: params,
_result: result
};
this.Debug(2, debug);
BackendService.Debug(2, debug);
try {
this.Debug(2, JSONBigNumber.parse(result, this.bigNumberParser));
BackendService.Debug(2, JSONBigNumber.parse(result, BackendService.bigNumberParser));
} catch (e) {
this.Debug(2, {response_data: result, error_code: 'OK'});
BackendService.Debug(2, {response_data: result, error_code: 'OK'});
}
}
private asVal(data) {
return {v: data};
}
private backendCallback(resultStr, params, callback, command) {
let Result = resultStr;
if (command !== 'get_clipboard') {
@ -179,7 +183,7 @@ export class BackendService {
Result = {};
} else {
try {
Result = JSONBigNumber.parse(resultStr, this.bigNumberParser);
Result = JSONBigNumber.parse(resultStr, BackendService.bigNumberParser);
} catch (e) {
Result = {response_data: resultStr, error_code: 'OK'};
}
@ -194,7 +198,7 @@ export class BackendService {
const Status = (Result.error_code === 'OK' || Result.error_code === 'TRUE');
if (!Status && Status !== undefined && Result.error_code !== undefined) {
this.Debug(1, 'API error for command: "' + command + '". Error code: ' + Result.error_code);
BackendService.Debug(1, 'API error for command: "' + command + '". Error code: ' + Result.error_code);
}
const data = ((typeof Result === 'object') && 'response_data' in Result) ? Result.response_data : Result;
@ -220,7 +224,7 @@ export class BackendService {
if (this.backendObject) {
const Action = this.backendObject[command];
if (!Action) {
this.Debug(0, 'Run Command Error! Command "' + command + '" don\'t found in backendObject');
BackendService.Debug(0, 'Run Command Error! Command "' + command + '" don\'t found in backendObject');
} else {
const that = this;
params = (typeof params === 'string') ? params : JSONBigNumber.stringify(params);
@ -245,7 +249,7 @@ export class BackendService {
this.backendObject[command].connect(callback);
} else {
this.backendObject[command].connect((str) => {
callback(JSONBigNumber.parse(str, this.bigNumberParser));
callback(JSONBigNumber.parse(str, BackendService.bigNumberParser));
});
}
}
@ -285,6 +289,12 @@ export class BackendService {
}
storeAppData(callback?) {
if (this.variablesService.wallets.length) {
this.variablesService.settings.wallets = [];
this.variablesService.wallets.forEach((wallet) => {
this.variablesService.settings.wallets.push({name: wallet.name, path: wallet.path});
});
}
this.runCommand('store_app_data', this.variablesService.settings, callback);
}
@ -292,10 +302,7 @@ export class BackendService {
this.runCommand('get_secure_app_data', pass, callback);
}
storeSecureAppData(callback) {
if (this.variablesService.appPass === '') {
return callback(false);
}
storeSecureAppData(callback?) {
const wallets = [];
this.variablesService.wallets.forEach((wallet) => {
wallets.push({name: wallet.name, pass: wallet.pass, path: wallet.path});
@ -305,6 +312,12 @@ export class BackendService {
});
}
dropSecureAppData(callback?) {
this.backendObject['drop_secure_app_data']((dataStore) => {
this.backendCallback(dataStore, {}, callback, 'drop_secure_app_data');
});
}
haveSecureAppData(callback) {
this.runCommand('have_secure_app_data', {}, callback);
}
@ -346,7 +359,7 @@ export class BackendService {
this.runCommand('open_wallet', params, callback);
}
closeWallet(wallet_id, callback) {
closeWallet(wallet_id, callback?) {
this.runCommand('close_wallet', {wallet_id: +wallet_id}, callback);
}
@ -354,7 +367,7 @@ export class BackendService {
this.runCommand('get_smart_wallet_info', {wallet_id: +wallet_id}, callback);
}
runWallet(wallet_id, callback) {
runWallet(wallet_id, callback?) {
this.runCommand('run_wallet', {wallet_id: +wallet_id}, callback);
}
@ -418,7 +431,7 @@ export class BackendService {
fee: this.variablesService.default_fee_big,
b_fee: this.variablesService.default_fee_big
};
this.Debug(1, params);
BackendService.Debug(1, params);
this.runCommand('create_proposal', params, callback);
}
@ -426,7 +439,7 @@ export class BackendService {
const params = {
wallet_id: parseInt(wallet_id, 10)
};
this.Debug(1, params);
BackendService.Debug(1, params);
this.runCommand('get_contracts', params, callback);
}
@ -435,7 +448,7 @@ export class BackendService {
wallet_id: parseInt(wallet_id, 10),
contract_id: contract_id
};
this.Debug(1, params);
BackendService.Debug(1, params);
this.runCommand('accept_proposal', params, callback);
}
@ -445,7 +458,7 @@ export class BackendService {
contract_id: contract_id,
release_type: release_type // "normal" or "burn"
};
this.Debug(1, params);
BackendService.Debug(1, params);
this.runCommand('release_contract', params, callback);
}
@ -456,7 +469,7 @@ export class BackendService {
fee: this.variablesService.default_fee_big,
expiration_period: parseInt(time, 10) * 60 * 60
};
this.Debug(1, params);
BackendService.Debug(1, params);
this.runCommand('request_cancel_contract', params, callback);
}
@ -465,7 +478,7 @@ export class BackendService {
wallet_id: parseInt(wallet_id, 10),
contract_id: contract_id
};
this.Debug(1, params);
BackendService.Debug(1, params);
this.runCommand('accept_cancel_contract', params, callback);
}
@ -506,7 +519,7 @@ export class BackendService {
this.runCommand('set_localization_strings', params, callback);
}
registerAlias (wallet_id, alias, address, fee, comment, reward, callback) {
registerAlias(wallet_id, alias, address, fee, comment, reward, callback) {
const params = {
wallet_id: wallet_id,
alias: {
@ -521,7 +534,7 @@ export class BackendService {
this.runCommand('request_alias_registration', params, callback);
}
updateAlias (wallet_id, alias, fee, callback) {
updateAlias(wallet_id, alias, fee, callback) {
const params = {
wallet_id: wallet_id,
alias: {
@ -535,24 +548,24 @@ export class BackendService {
this.runCommand('request_alias_update', params, callback);
}
getAllAliases (callback) {
getAllAliases(callback) {
this.runCommand('get_all_aliases', {}, callback);
}
getAliasByName (value, callback) {
getAliasByName(value, callback) {
return this.runCommand('get_alias_info_by_name', value, callback);
}
getAliasByAddress (value, callback) {
getAliasByAddress(value, callback) {
return this.runCommand('get_alias_info_by_address', value, callback);
}
getAliasCoast (alias, callback) {
getAliasCoast(alias, callback) {
this.runCommand('get_alias_coast', {v: alias}, callback);
}
getWalletAlias(address) {
if (address != null && this.variablesService.daemon_state === 2) {
if (address !== null && this.variablesService.daemon_state === 2) {
if (this.variablesService.aliasesChecked[address] == null) {
this.variablesService.aliasesChecked[address] = {};
if (this.variablesService.aliases.length) {

View file

@ -13,6 +13,7 @@ export class VariablesService {
public digits = 12;
public appPass = '';
public appLogin = false;
public moneyEquivalent = 0;
public defaultTheme = 'dark';
public defaultCurrency = 'ZAN';
@ -35,7 +36,8 @@ export class VariablesService {
language: 'en',
default_path: '/',
viewedContracts: [],
notViewedContracts: []
notViewedContracts: [],
wallets: []
};
public wallets: Array<Wallet> = [];
@ -46,6 +48,7 @@ export class VariablesService {
public maxWalletNameLength = 25;
public maxCommentLength = 255;
getExpMedTsEvent = new BehaviorSubject(null);
getHeightAppEvent = new BehaviorSubject(null);
getRefreshStackingEvent = new BehaviorSubject(null);
getAliasChangedEvent = new BehaviorSubject(null);
@ -56,6 +59,7 @@ export class VariablesService {
this.ngZone.run(() => {
this.idle.stop();
this.appPass = '';
this.appLogin = false;
this.router.navigate(['/login'], {queryParams: {type: 'auth'}});
});
});
@ -67,6 +71,13 @@ export class VariablesService {
constructor(private router: Router, private ngZone: NgZone, private contextMenuService: ContextMenuService) {
}
setExpMedTs(timestamp: number) {
if (timestamp !== this.exp_med_ts) {
this.exp_med_ts = timestamp;
this.getExpMedTsEvent.next(timestamp);
}
}
setHeightApp(height: number) {
if (height !== this.height_app) {
this.height_app = height;

View file

@ -1,4 +1,4 @@
<app-sidebar *ngIf="variablesService.appPass"></app-sidebar>
<app-sidebar *ngIf="variablesService.appLogin"></app-sidebar>
<div class="app-content scrolled-content">
<router-outlet *ngIf="[0, 1, 2].indexOf(variablesService.daemon_state) !== -1"></router-outlet>
@ -24,3 +24,6 @@
<ng-template contextMenuItem (execute)="contextMenuPaste($event.item)">{{ 'CONTEXT_MENU.PASTE' | translate }}</ng-template>
<ng-template contextMenuItem (execute)="contextMenuSelect($event.item)">{{ 'CONTEXT_MENU.SELECT' | translate }}</ng-template>
</context-menu>
<app-open-wallet-modal *ngIf="needOpenWallets.length" [wallets]="needOpenWallets"></app-open-wallet-modal>

View file

@ -17,9 +17,12 @@ import {ModalService} from './_helpers/services/modal.service';
export class AppComponent implements OnInit, OnDestroy {
intervalUpdateContractsState;
expMedTsEvent;
onQuitRequest = false;
firstOnlineState = false;
needOpenWallets = [];
@ViewChild('allContextMenu') public allContextMenu: ContextMenuComponent;
@ViewChild('onlyCopyContextMenu') public onlyCopyContextMenu: ContextMenuComponent;
@ -75,8 +78,9 @@ export class AppComponent implements OnInit, OnDestroy {
this.ngZone.run(() => {
this.router.navigate(['/']);
});
this.needOpenWallets = [];
this.variablesService.daemon_state = 5;
this.backend.storeSecureAppData(() => {
const saveFunction = () => {
this.backend.storeAppData(() => {
const recursionCloseWallets = () => {
if (this.variablesService.wallets.length) {
@ -91,7 +95,14 @@ export class AppComponent implements OnInit, OnDestroy {
};
recursionCloseWallets();
});
});
};
if (this.variablesService.appPass) {
this.backend.storeSecureAppData(() => {
saveFunction();
});
} else {
saveFunction();
}
}
this.onQuitRequest = true;
});
@ -144,7 +155,8 @@ export class AppComponent implements OnInit, OnDestroy {
console.log('----------------- update_daemon_state -----------------');
console.log('DAEMON:' + data.daemon_network_state);
console.log(data);
this.variablesService.exp_med_ts = data['expiration_median_timestamp'] + 600 + 1;
// this.variablesService.exp_med_ts = data['expiration_median_timestamp'] + 600 + 1;
this.variablesService.setExpMedTs(data['expiration_median_timestamp'] + 600 + 1);
this.variablesService.last_build_available = data.last_build_available;
this.variablesService.setHeightApp(data.height);
@ -386,7 +398,8 @@ export class AppComponent implements OnInit, OnDestroy {
for (let i = 0, length = data.events.length; i < length; i++) {
switch (data.events[i].method) {
case 'CORE_EVENT_BLOCK_ADDED': break;
case 'CORE_EVENT_BLOCK_ADDED':
break;
case 'CORE_EVENT_ADD_ALIAS':
if (this.variablesService.aliasesChecked[data.events[i].details.address] != null) {
this.variablesService.aliasesChecked[data.events[i].details.address]['name'] = '@' + data.events[i].details.alias;
@ -439,7 +452,8 @@ export class AppComponent implements OnInit, OnDestroy {
}
this.variablesService.changeAliases();
break;
default: break;
default:
break;
}
}
}
@ -460,6 +474,22 @@ export class AppComponent implements OnInit, OnDestroy {
});
}, 30000);
this.expMedTsEvent = this.variablesService.getExpMedTsEvent.subscribe((newTimestamp: number) => {
this.variablesService.wallets.forEach((wallet) => {
wallet.contracts.forEach((contract) => {
if (contract.state === 1 && contract.expiration_time <= newTimestamp) {
contract.state = 110;
contract.is_new = true;
wallet.recountNewContracts();
} else if (contract.state === 5 && contract.cancel_expiration_time <= newTimestamp) {
contract.state = 130;
contract.is_new = true;
wallet.recountNewContracts();
}
});
});
});
this.backend.getAppData((status, data) => {
if (data && Object.keys(data).length > 0) {
@ -490,9 +520,17 @@ export class AppComponent implements OnInit, OnDestroy {
this.router.navigate(['/login'], {queryParams: {type: 'auth'}});
});
} else {
this.ngZone.run(() => {
this.router.navigate(['/login'], {queryParams: {type: 'reg'}});
});
if (Object.keys(data).length !== 0) {
this.needOpenWallets = JSON.parse(JSON.stringify(this.variablesService.settings.wallets));
this.ngZone.run(() => {
this.variablesService.appLogin = true;
this.router.navigate(['/']);
});
} else {
this.ngZone.run(() => {
this.router.navigate(['/login'], {queryParams: {type: 'reg'}});
});
}
}
});
}
@ -521,6 +559,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();
@ -528,6 +569,9 @@ export class AppComponent implements OnInit, OnDestroy {
} else if (error === 'OVERFLOW') {
this.variablesService.aliases = [];
this.variablesService.enableAliasSearch = false;
this.variablesService.wallets.forEach(wallet => {
wallet.alias = this.backend.getWalletAlias(wallet.address);
});
} else {
this.variablesService.enableAliasSearch = true;
if (data.aliases && data.aliases.length) {
@ -544,10 +588,18 @@ export class AppComponent implements OnInit, OnDestroy {
wallet.alias = this.backend.getWalletAlias(wallet.address);
});
this.variablesService.aliases = this.variablesService.aliases.sort((a, b) => {
if (a.name.length > b.name.length) return 1;
if (a.name.length < b.name.length) return -1;
if (a.name > b.name) return 1;
if (a.name < b.name) return -1;
if (a.name.length > b.name.length) {
return 1;
}
if (a.name.length < b.name.length) {
return -1;
}
if (a.name > b.name) {
return 1;
}
if (a.name < b.name) {
return -1;
}
return 0;
});
this.variablesService.changeAliases();
@ -608,6 +660,7 @@ export class AppComponent implements OnInit, OnDestroy {
if (this.intervalUpdateContractsState) {
clearInterval(this.intervalUpdateContractsState);
}
this.expMedTsEvent.unsubscribe();
}
}

View file

@ -10,6 +10,7 @@ import { SidebarComponent } from './sidebar/sidebar.component';
import { MainComponent } from './main/main.component';
import { CreateWalletComponent } from './create-wallet/create-wallet.component';
import { OpenWalletComponent } from './open-wallet/open-wallet.component';
import { OpenWalletModalComponent } from './open-wallet-modal/open-wallet-modal.component';
import { RestoreWalletComponent } from './restore-wallet/restore-wallet.component';
import { SeedPhraseComponent } from './seed-phrase/seed-phrase.component';
import { WalletDetailsComponent } from './wallet-details/wallet-details.component';
@ -73,6 +74,7 @@ Highcharts.setOptions({
MainComponent,
CreateWalletComponent,
OpenWalletComponent,
OpenWalletModalComponent,
RestoreWalletComponent,
SeedPhraseComponent,
WalletDetailsComponent,

View file

@ -31,8 +31,8 @@
<div>{{item.private_detailes.to_pay | intToMoney}} {{variablesService.defaultCurrency}}</div>
</td>
<td>
<div class="status" [class.error-text]="item.state === 4" tooltip="{{ item | contractStatusMessages }}" placement="top" tooltipClass="table-tooltip" [delay]="500">
{{item | contractStatusMessages}}
<div class="status" [class.error-text]="item.state === 4" tooltip="{{item.state | contractStatusMessages : item.is_a}}" placement="top" tooltipClass="table-tooltip" [delay]="500">
{{item.state | contractStatusMessages : item.is_a}}
</div>
</td>
<td>

View file

@ -1,5 +1,5 @@
import {Component, OnInit, OnDestroy} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {ActivatedRoute} from '@angular/router';
import {VariablesService} from '../_helpers/services/variables.service';
@Component({
@ -14,8 +14,7 @@ export class ContractsComponent implements OnInit, OnDestroy {
constructor(
private route: ActivatedRoute,
private router: Router,
private variablesService: VariablesService
public variablesService: VariablesService
) {
}

View file

@ -77,6 +77,7 @@ export class CreateWalletComponent implements OnInit {
generate_data['wi'].mined_total,
generate_data['wi'].tracking_hey
);
this.variablesService.opening_wallet.alias = this.backend.getWalletAlias(generate_data['wi'].address);
this.ngZone.run(() => {
this.walletSaved = true;
this.progressWidth = '50%';

View file

@ -9,21 +9,11 @@
<div class="input-block">
<label for="master-pass">{{ 'LOGIN.SETUP_MASTER_PASS' | translate }}</label>
<input type="password" id="master-pass" formControlName="password" (contextmenu)="variablesService.onContextMenuPasteSelect($event)">
<div class="error-block" *ngIf="regForm.controls['password'].invalid && (regForm.controls['password'].dirty || regForm.controls['password'].touched)">
<div *ngIf="regForm.controls['password'].errors['required']">
{{ 'LOGIN.FORM_ERRORS.PASS_REQUIRED' | translate }}
</div>
</div>
</div>
<div class="input-block">
<label for="confirm-pass">{{ 'LOGIN.SETUP_CONFIRM_PASS' | translate }}</label>
<input type="password" id="confirm-pass" formControlName="confirmation" (contextmenu)="variablesService.onContextMenuPasteSelect($event)">
<div class="error-block" *ngIf="regForm.controls['confirmation'].invalid && (regForm.controls['confirmation'].dirty || regForm.controls['confirmation'].touched)">
<div *ngIf="regForm.controls['confirmation'].errors['required']">
{{ 'LOGIN.FORM_ERRORS.CONFIRM_REQUIRED' | translate }}
</div>
</div>
<div class="error-block" *ngIf="regForm.controls['password'].dirty && regForm.controls['confirmation'].dirty && regForm.errors">
<div *ngIf="regForm.errors['mismatch']">
{{ 'LOGIN.FORM_ERRORS.MISMATCH' | translate }}
@ -31,7 +21,10 @@
</div>
</div>
<button type="submit" class="blue-button">{{ 'LOGIN.BUTTON_NEXT' | translate }}</button>
<div class="wrap-button">
<button type="submit" class="blue-button" [disabled]="!regForm.controls['password'].value.length || !regForm.controls['confirmation'].value.length || (regForm.errors && regForm.errors['mismatch'])">{{ 'LOGIN.BUTTON_NEXT' | translate }}</button>
<button type="button" class="blue-button" (click)="onSkipCreatePass()" [disabled]="regForm.controls['password'].value.length || regForm.controls['confirmation'].value.length">{{ 'LOGIN.BUTTON_SKIP' | translate }}</button>
</div>
</form>
@ -40,11 +33,6 @@
<div class="input-block">
<label for="master-pass-login">{{ 'LOGIN.MASTER_PASS' | translate }}</label>
<input type="password" id="master-pass-login" formControlName="password" autofocus (contextmenu)="variablesService.onContextMenuPasteSelect($event)">
<div class="error-block" *ngIf="authForm.controls['password'].invalid && (authForm.controls['password'].dirty || authForm.controls['password'].touched)">
<div *ngIf="authForm.controls['password'].errors['required']">
{{ 'LOGIN.FORM_ERRORS.PASS_REQUIRED' | translate }}
</div>
</div>
</div>
<button type="submit" class="blue-button">{{ 'LOGIN.BUTTON_NEXT' | translate }}</button>

View file

@ -16,13 +16,23 @@
.logo {
background: url(../../assets/icons/logo.svg) no-repeat center;
width: 100%;
height: 20rem;
height: 15rem;
}
.form-login {
display: flex;
flex-direction: column;
.wrap-button {
display: flex;
align-items: center;
justify-content: space-between;
button {
margin: 2.5rem 0;
}
}
button {
margin: 2.5rem auto;
width: 100%;

View file

@ -16,14 +16,14 @@ export class LoginComponent implements OnInit, OnDestroy {
queryRouting;
regForm = new FormGroup({
password: new FormControl('', Validators.required),
confirmation: new FormControl('', Validators.required)
password: new FormControl(''),
confirmation: new FormControl('')
}, function (g: FormGroup) {
return g.get('password').value === g.get('confirmation').value ? null : {'mismatch': true};
});
authForm = new FormGroup({
password: new FormControl('', Validators.required)
password: new FormControl('')
});
type = 'reg';
@ -32,7 +32,7 @@ export class LoginComponent implements OnInit, OnDestroy {
private route: ActivatedRoute,
private router: Router,
private backend: BackendService,
private variablesService: VariablesService,
public variablesService: VariablesService,
private modalService: ModalService,
private ngZone: NgZone
) {
@ -51,6 +51,8 @@ export class LoginComponent implements OnInit, OnDestroy {
this.variablesService.appPass = this.regForm.get('password').value;
this.backend.storeSecureAppData((status, data) => {
if (status) {
this.variablesService.appLogin = true;
this.variablesService.startCountdown();
this.ngZone.run(() => {
this.router.navigate(['/']);
});
@ -61,11 +63,20 @@ export class LoginComponent implements OnInit, OnDestroy {
}
}
onSkipCreatePass(): void {
this.variablesService.appPass = '';
this.ngZone.run(() => {
this.variablesService.appLogin = true;
this.router.navigate(['/']);
});
}
onSubmitAuthPass(): void {
if (this.authForm.valid) {
const appPass = this.authForm.get('password').value;
this.backend.getSecureAppData({pass: appPass}, (status, data) => {
if (!data.error_code) {
this.variablesService.appLogin = true;
this.variablesService.startCountdown();
this.variablesService.appPass = appPass;
if (this.variablesService.wallets.length) {

View file

@ -0,0 +1,18 @@
<div class="modal">
<h3 class="title">{{ 'OPEN_WALLET.MODAL.TITLE' | translate }}</h3>
<form class="open-form" (ngSubmit)="openWallet()">
<div class="wallet-path">{{ wallet.name }}</div>
<div class="wallet-path">{{ wallet.path }}</div>
<div class="input-block" *ngIf="!wallet.notFound && !wallet.emptyPass">
<label for="password">{{ 'OPEN_WALLET.MODAL.LABEL' | translate }}</label>
<input type="password" id="password" name="password" [(ngModel)]="wallet.pass" (contextmenu)="variablesService.onContextMenuPasteSelect($event)"/>
</div>
<div class="error-block" *ngIf="wallet.notFound">
{{ 'OPEN_WALLET.MODAL.NOT_FOUND' | translate }}
</div>
<div class="wrap-button">
<button type="submit" class="blue-button" [disabled]="wallet.notFound">{{ 'OPEN_WALLET.MODAL.OPEN' | translate }}</button>
<button type="button" class="blue-button" (click)="skipWallet()">{{ 'OPEN_WALLET.MODAL.SKIP' | translate }}</button>
</div>
</form>
</div>

View file

@ -0,0 +1,45 @@
:host {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.25);
}
.modal {
display: flex;
flex-direction: column;
background-position: center;
background-size: 200%;
padding: 2rem;
width: 34rem;
.title {
font-size: 1.8rem;
text-align: center;
}
.open-form {
.wallet-path {
font-size: 1.3rem;
margin: 5rem 0 2rem;
}
.wrap-button {
display: flex;
align-items: center;
justify-content: space-between;
margin: 2rem -2rem 0;
button {
flex: 1 0 0;
margin: 0 2rem ;
}
}
}
}

View file

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { OpenWalletModalComponent } from './open-wallet-modal.component';
describe('OpenWalletModalComponent', () => {
let component: OpenWalletModalComponent;
let fixture: ComponentFixture<OpenWalletModalComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ OpenWalletModalComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(OpenWalletModalComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,121 @@
import {Component, OnInit, Input, NgZone} from '@angular/core';
import {VariablesService} from '../_helpers/services/variables.service';
import {Wallet} from '../_helpers/models/wallet.model';
import {BackendService} from '../_helpers/services/backend.service';
import {TranslateService} from '@ngx-translate/core';
import {ModalService} from '../_helpers/services/modal.service';
@Component({
selector: 'app-open-wallet-modal',
templateUrl: './open-wallet-modal.component.html',
styleUrls: ['./open-wallet-modal.component.scss']
})
export class OpenWalletModalComponent implements OnInit {
@Input() wallets;
wallet = {
name: '',
path: '',
pass: '',
notFound: false,
emptyPass: false
};
constructor(
public variablesService: VariablesService,
private backend: BackendService,
private translate: TranslateService,
private modalService: ModalService,
private ngZone: NgZone,
) {
}
ngOnInit() {
if (this.wallets.length) {
this.wallet = this.wallets[0];
this.wallet.pass = '';
this.backend.openWallet(this.wallet.path, '', true, (status, data, error) => {
if (error === 'FILE_NOT_FOUND') {
this.wallet.notFound = true;
}
if (status) {
this.wallet.pass = '';
this.wallet.emptyPass = true;
this.backend.closeWallet(data.wallet_id);
this.openWallet();
}
});
}
}
openWallet() {
if (this.wallets.length === 0) {
return;
}
this.backend.openWallet(this.wallet.path, this.wallet.pass, false, (open_status, open_data, open_error) => {
if (open_error && open_error === 'FILE_NOT_FOUND') {
let error_translate = this.translate.instant('OPEN_WALLET.FILE_NOT_FOUND1');
error_translate += ':<br>' + this.wallet.path;
error_translate += this.translate.instant('OPEN_WALLET.FILE_NOT_FOUND2');
this.modalService.prepareModal('error', error_translate);
} else {
if (open_status || open_error === 'FILE_RESTORED') {
let exists = false;
this.variablesService.wallets.forEach((wallet) => {
if (wallet.address === open_data['wi'].address) {
exists = true;
}
});
if (exists) {
this.modalService.prepareModal('error', 'OPEN_WALLET.WITH_ADDRESS_ALREADY_OPEN');
this.backend.closeWallet(open_data.wallet_id);
} else {
const new_wallet = new Wallet(
open_data.wallet_id,
this.wallet.name,
this.wallet.pass,
open_data['wi'].path,
open_data['wi'].address,
open_data['wi'].balance,
open_data['wi'].unlocked_balance,
open_data['wi'].mined_total,
open_data['wi'].tracking_hey
);
new_wallet.alias = this.backend.getWalletAlias(new_wallet.address);
if (open_data.recent_history && open_data.recent_history.history) {
new_wallet.prepareHistory(open_data.recent_history.history);
}
this.backend.getContracts(open_data.wallet_id, (contracts_status, contracts_data) => {
if (contracts_status && contracts_data.hasOwnProperty('contracts')) {
this.ngZone.run(() => {
new_wallet.prepareContractsAfterOpen(
contracts_data.contracts,
this.variablesService.exp_med_ts,
this.variablesService.height_app,
this.variablesService.settings.viewedContracts,
this.variablesService.settings.notViewedContracts
);
});
}
});
this.variablesService.wallets.push(new_wallet);
this.backend.runWallet(open_data.wallet_id);
this.skipWallet();
}
}
}
});
}
skipWallet() {
if (this.wallets.length) {
this.wallets.splice(0, 1);
this.ngOnInit();
}
}
}

View file

@ -110,9 +110,9 @@ export class OpenWalletComponent implements OnInit, OnDestroy {
this.variablesService.wallets.push(new_wallet);
this.backend.runWallet(open_data.wallet_id, (run_status, run_data) => {
if (run_status) {
this.backend.storeSecureAppData((status, data) => {
console.log('Store App Data', status, data);
});
if (this.variablesService.appPass) {
this.backend.storeSecureAppData();
}
this.ngZone.run(() => {
this.router.navigate(['/wallet/' + open_data.wallet_id]);
});

View file

@ -1,5 +1,5 @@
import {Component, NgZone, OnDestroy, OnInit} from '@angular/core';
import {Location} from "@angular/common";
import {Location} from '@angular/common';
import {BackendService} from '../_helpers/services/backend.service';
import {ActivatedRoute, Router} from '@angular/router';
import {VariablesService} from '../_helpers/services/variables.service';
@ -52,9 +52,9 @@ export class SeedPhraseComponent implements OnInit, OnDestroy {
this.backend.runWallet(this.wallet_id, (run_status, run_data) => {
if (run_status) {
this.variablesService.wallets.push(this.variablesService.opening_wallet);
this.backend.storeSecureAppData((status, data) => {
console.log('Store App Data', status, data);
});
if (this.variablesService.appPass) {
this.backend.storeSecureAppData();
}
this.ngZone.run(() => {
this.router.navigate(['/wallet/' + this.wallet_id]);
});

View file

@ -54,14 +54,9 @@
<span class="master-password-title">{{ 'SETTINGS.MASTER_PASSWORD.TITLE' | translate }}</span>
<div class="input-block">
<div class="input-block" *ngIf="variablesService.appPass">
<label for="old-password">{{ 'SETTINGS.MASTER_PASSWORD.OLD' | translate }}</label>
<input type="password" id="old-password" formControlName="password" (contextmenu)="variablesService.onContextMenuPasteSelect($event)"/>
<div class="error-block" *ngIf="changeForm.controls['password'].invalid && (changeForm.controls['password'].dirty || changeForm.controls['password'].touched)">
<div *ngIf="changeForm.controls['password'].errors['required']">
{{ 'SETTINGS.FORM_ERRORS.PASS_REQUIRED' | translate }}
</div>
</div>
<div class="error-block" *ngIf="changeForm.invalid && changeForm.controls['password'].valid && (changeForm.controls['password'].dirty || changeForm.controls['password'].touched) && changeForm.errors && changeForm.errors.pass_mismatch">
{{ 'SETTINGS.FORM_ERRORS.PASS_NOT_MATCH' | translate }}
</div>
@ -70,21 +65,11 @@
<div class="input-block">
<label for="new-password">{{ 'SETTINGS.MASTER_PASSWORD.NEW' | translate }}</label>
<input type="password" id="new-password" formControlName="new_password" (contextmenu)="variablesService.onContextMenuPasteSelect($event)"/>
<div class="error-block" *ngIf="changeForm.controls['new_password'].invalid && (changeForm.controls['new_password'].dirty || changeForm.controls['new_password'].touched)">
<div *ngIf="changeForm.controls['new_password'].errors['required']">
{{ 'SETTINGS.FORM_ERRORS.PASS_REQUIRED' | translate }}
</div>
</div>
</div>
<div class="input-block">
<label for="confirm-password">{{ 'SETTINGS.MASTER_PASSWORD.CONFIRM' | translate }}</label>
<input type="password" id="confirm-password" formControlName="new_confirmation" (contextmenu)="variablesService.onContextMenuPasteSelect($event)"/>
<div class="error-block" *ngIf="changeForm.controls['new_confirmation'].invalid && (changeForm.controls['new_confirmation'].dirty || changeForm.controls['new_confirmation'].touched)">
<div *ngIf="changeForm.controls['new_confirmation'].errors['required']">
{{ 'SETTINGS.FORM_ERRORS.PASS_REQUIRED' | translate }}
</div>
</div>
<div class="error-block" *ngIf="changeForm.invalid && (changeForm.controls['new_confirmation'].dirty || changeForm.controls['new_confirmation'].touched) && changeForm.errors && changeForm.errors.confirm_mismatch">
{{ 'SETTINGS.FORM_ERRORS.CONFIRM_NOT_MATCH' | translate }}
</div>

View file

@ -1,7 +1,7 @@
import {Component, NgZone, OnInit, Renderer2} from '@angular/core';
import {VariablesService} from '../_helpers/services/variables.service';
import {BackendService} from '../_helpers/services/backend.service';
import {FormControl, FormGroup, Validators} from '@angular/forms';
import {FormControl, FormGroup} from '@angular/forms';
import {Location} from '@angular/common';
@Component({
@ -63,13 +63,16 @@ export class SettingsComponent implements OnInit {
this.theme = this.variablesService.settings.theme;
this.scale = this.variablesService.settings.scale;
this.changeForm = new FormGroup({
password: new FormControl('', Validators.required),
new_password: new FormControl('', Validators.required),
new_confirmation: new FormControl('', Validators.required)
password: new FormControl(''),
new_password: new FormControl(''),
new_confirmation: new FormControl('')
}, [(g: FormGroup) => {
return g.get('new_password').value === g.get('new_confirmation').value ? null : {'confirm_mismatch': true};
}, (g: FormGroup) => {
return g.get('password').value === this.variablesService.appPass ? null : {'pass_mismatch': true};
if (this.variablesService.appPass) {
return g.get('password').value === this.variablesService.appPass ? null : {'pass_mismatch': true};
}
return null;
}]);
}
@ -99,18 +102,19 @@ export class SettingsComponent implements OnInit {
onSubmitChangePass() {
if (this.changeForm.valid) {
this.variablesService.appPass = this.changeForm.get('new_password').value;
this.backend.storeSecureAppData((status, data) => {
if (status) {
this.changeForm.reset();
} else {
console.log(data);
}
});
if (this.variablesService.appPass) {
this.backend.storeSecureAppData();
} else {
this.backend.dropSecureAppData();
}
this.changeForm.reset();
}
}
onLockChange() {
this.variablesService.restartCountdown();
if (this.variablesService.appLogin) {
this.variablesService.restartCountdown();
}
this.backend.storeAppData();
}

View file

@ -9,13 +9,13 @@
<span class="balance">{{wallet.balance | intToMoney : '3' }} {{variablesService.defaultCurrency}}</span>
</div>
<div class="sidebar-account-row account-alias">
<div style="display: flex; align-items: center;">
<span>{{wallet.alias['name']}}</span>
<div class="name">
<span tooltip="{{wallet.alias['name']}}" placement="top-left" tooltipClass="table-tooltip account-tooltip" [delay]="500" [showWhenNoOverflow]="false">{{wallet.alias['name']}}</span>
<ng-container *ngIf="wallet.alias['comment'] && wallet.alias['comment'].length">
<i class="icon comment" tooltip="{{wallet.alias['comment']}}" placement="top" tooltipClass="table-tooltip account-tooltip" [delay]="500"></i>
</ng-container>
</div>
<span>$ {{wallet.getMoneyEquivalent(variablesService.moneyEquivalent) | intToMoney | number : '1.2-2'}}</span>
<span class="price">$ {{wallet.getMoneyEquivalent(variablesService.moneyEquivalent) | intToMoney | number : '1.2-2'}}</span>
</div>
<div class="sidebar-account-row account-staking" *ngIf="!(!wallet.loaded && variablesService.daemon_state === 2)">
<span class="text">{{ 'SIDEBAR.ACCOUNT.STAKING' | translate }}</span>

View file

@ -72,6 +72,25 @@
line-height: 3.4rem;
margin-bottom: 0.7rem;
.name {
display: flex;
align-items: center;
flex-shrink: 1;
line-height: 1.6rem;
padding-right: 1rem;
overflow: hidden;
span {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
.price {
flex-shrink: 0;
}
.icon {
margin-left: 0.5rem;
width: 1.2rem;

View file

@ -49,6 +49,7 @@ export class SidebarComponent implements OnInit, OnDestroy {
logOut() {
this.variablesService.stopCountdown();
this.variablesService.appLogin = false;
this.variablesService.appPass = '';
this.ngZone.run(() => {
this.router.navigate(['/login'], {queryParams: {type: 'auth'}});

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

@ -72,16 +72,17 @@ export class WalletDetailsComponent implements OnInit, OnDestroy {
this.variablesService.wallets.splice(i, 1);
}
}
this.backend.storeSecureAppData(() => {
this.ngZone.run(() => {
if (this.variablesService.wallets.length) {
this.variablesService.currentWallet = this.variablesService.wallets[0];
this.router.navigate(['/wallet/' + this.variablesService.currentWallet.wallet_id]);
} else {
this.router.navigate(['/']);
}
});
this.ngZone.run(() => {
if (this.variablesService.wallets.length) {
this.variablesService.currentWallet = this.variablesService.wallets[0];
this.router.navigate(['/wallet/' + this.variablesService.currentWallet.wallet_id]);
} else {
this.router.navigate(['/']);
}
});
if (this.variablesService.appPass) {
this.backend.storeSecureAppData();
}
});
}

View file

@ -4,6 +4,7 @@
"SETUP_CONFIRM_PASS": "Confirm the password",
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required.",
@ -83,6 +84,13 @@
"NAME_REQUIRED": "Name is required.",
"NAME_DUPLICATE": "Name is duplicate.",
"MAX_LENGTH": "Maximum name length reached."
},
"MODAL": {
"TITLE": "Type wallet password",
"LABEL": "Password to this wallet",
"OPEN": "Open wallet",
"SKIP": "Skip",
"NOT_FOUND": "Not found"
}
},
"RESTORE_WALLET": {
@ -440,11 +448,21 @@
"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"

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 {
@ -597,6 +625,10 @@ input[type='checkbox'].style-checkbox {
.ng-value-container {
padding: 0;
.ng-input {
top: auto;
}
}
}
@ -752,3 +784,14 @@ app-progress-container {
}
}
}
app-open-wallet-modal {
.modal {
@include themify($themes) {
background: themed(modalBackground);
color: themed(mainTextColor);
}
}
}

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);
}
}
}
}

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();
@ -802,7 +804,7 @@ namespace currency
LOG_ERROR("Failed to create block template");
return false;
}
res.difficulty = dt.convert_to<uint64_t>();
res.difficulty = dt.convert_to<std::string>();
blobdata block_blob = t_serializable_object_to_blob(b);
res.blocktemplate_blob = string_tools::buff_to_hex_nodelimer(block_blob);
@ -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;
}
@ -1110,7 +1112,7 @@ namespace currency
set_session_blob(job_id, b);
job.blob = string_tools::buff_to_hex_nodelimer(currency::get_block_hashing_blob(b));
//TODO: set up share difficulty here!
job.difficulty = std::to_string(bt_res.difficulty); //difficulty leaved as string field since it will be refactored into 128 bit format
job.difficulty = bt_res.difficulty; //difficulty leaved as string field since it will be refactored into 128 bit format
job.job_id = "SOME_JOB_ID";
get_current_hi(job.prev_hi);
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)
@ -788,7 +791,7 @@ namespace currency
struct response
{
uint64_t difficulty;
std::string difficulty;
uint64_t height;
crypto::hash seed;
blobdata blocktemplate_blob;
@ -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

@ -2,6 +2,6 @@
#define BUILD_COMMIT_ID "@VERSION@"
#define PROJECT_VERSION "1.0"
#define PROJECT_VERSION_BUILD_NO 14
#define PROJECT_VERSION_BUILD_NO 16
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"

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

@ -628,7 +628,7 @@ bool gen_no_attchments_in_coinbase::init_config_set_cp(currency::core& c, size_t
crc.pos_minimum_heigh = 1;
c.get_blockchain_storage().set_core_runtime_config(crc);
m_checkpoints.add_checkpoint(12, "446b25ca3816e36df92745ea91c3c54a8745db565bafd4d2aa7df9da49220a19");
m_checkpoints.add_checkpoint(12, "ea03a5c99aeedc2050ca5dae011a6c411b31f8b7fb9d0b82735c403b5c608b7b");
c.set_checkpoints(currency::checkpoints(m_checkpoints));
return true;

View file

@ -1625,7 +1625,7 @@ multisig_and_checkpoints::multisig_and_checkpoints()
bool multisig_and_checkpoints::set_cp(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
{
currency::checkpoints checkpoints;
checkpoints.add_checkpoint(15, "37da2a30fd8cf1daa05ba11cb2ac5f7a3cc998bce56e4b575fbbea58f0592f5b");
checkpoints.add_checkpoint(15, "46f45b849160be33937c60fa564e820792b0aaa6cf4a080e6002b6f25d84d688");
c.set_checkpoints(std::move(checkpoints));
return true;

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

@ -589,7 +589,7 @@ bool transactions_flow_test(
if (action == TRANSACTIONS_FLOW_TESTACTION_MIXED)
{
current_action++;
if (current_action > TRANSACTIONS_FLOW_TESTACTION_OFFERS)
if (current_action >= TRANSACTIONS_FLOW_TESTACTION_OFFERS)
current_action = TRANSACTIONS_FLOW_TESTACTION_DEFAULT;
}
}

View file

@ -264,7 +264,7 @@ 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;
auto create_and_destroy_connections = [this]()
auto create_and_destroy_connections = [&]()
{
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

View file

@ -12,4 +12,4 @@ EOM
esac
printf "tx_daily_count.value "
connectivity_tool --ip=127.0.0.1 --rpc-port=$ZANO_RPC_PORT --timeout=1000 --rpc-get-daemon-info --getinfo-flags-hex="0x0000000000000080" | grep transactions_cnt_per_day | cut -d ' ' -f2
connectivity_tool --ip=127.0.0.1 --rpc-port=$ZANO_RPC_PORT --timeout=10000 --rpc-get-daemon-info --getinfo-flags-hex="0x0000000000000080" | grep transactions_cnt_per_day | cut -d ' ' -f2

View file

@ -12,4 +12,4 @@ EOM
esac
printf "tx_daily_volume.value "
connectivity_tool --ip=127.0.0.1 --rpc-port=$ZANO_RPC_PORT --timeout=1000 --rpc-get-daemon-info --getinfo-flags-hex="0x0000000000000080" | grep transactions_volume_per_day | cut -d ' ' -f2
connectivity_tool --ip=127.0.0.1 --rpc-port=$ZANO_RPC_PORT --timeout=10000 --rpc-get-daemon-info --getinfo-flags-hex="0x0000000000000080" | grep transactions_volume_per_day | cut -d ' ' -f2