forked from lthn/blockchain
implemented governance initial code for wallet/daemon
This commit is contained in:
parent
0ede461f25
commit
1886fae681
18 changed files with 309 additions and 12 deletions
|
|
@ -77,8 +77,7 @@ namespace epee
|
|||
bool insert_next_section(harray hSecArray, hsection& hinserted_childsection);
|
||||
//------------------------------------------------------------------------
|
||||
//delete entry (section, value or array)
|
||||
bool delete_entry(const std::string& pentry_name, hsection hparent_section = nullptr);
|
||||
|
||||
bool delete_entry(const std::string& pentry_name, hsection hparent_section = nullptr);
|
||||
//-------------------------------------------------------------------------------
|
||||
bool store_to_binary(binarybuffer& target);
|
||||
bool load_from_binary(const binarybuffer& target);
|
||||
|
|
@ -87,6 +86,8 @@ namespace epee
|
|||
bool dump_as_json(std::string& targetObj, size_t indent = 0, end_of_line_t eol = eol_crlf);
|
||||
bool load_from_json(const std::string& source);
|
||||
|
||||
template<typename cb_t>
|
||||
bool enum_entries(hsection hparent_section, cb_t cb);
|
||||
private:
|
||||
section m_root;
|
||||
hsection get_root_section() {return &m_root;}
|
||||
|
|
@ -384,6 +385,20 @@ namespace epee
|
|||
CATCH_ENTRY("portable_storage::insert_first_value", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<typename cb_t>
|
||||
bool portable_storage::enum_entries(hsection hparent_section, cb_t cb)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if (!hparent_section) hparent_section = &m_root;
|
||||
for (const auto& e : hparent_section->m_entries)
|
||||
{
|
||||
if (!cb(e.first, e.second))
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::enum_entries", false);
|
||||
}
|
||||
|
||||
template<class t_value>
|
||||
bool portable_storage::insert_next_value(harray hval_array, const t_value& target)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <cctype>
|
||||
#include "warnings.h"
|
||||
|
||||
|
||||
|
|
@ -310,7 +311,14 @@ namespace string_encoding
|
|||
return get_md5_as_hexstring(src.data(), src.size());
|
||||
}
|
||||
#endif
|
||||
|
||||
inline
|
||||
std::string toupper(std::string s)
|
||||
{
|
||||
std::transform(s.begin(), s.end(), s.begin(),
|
||||
[](unsigned char c) { return std::toupper(c); } // correct
|
||||
);
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2808,6 +2808,51 @@ size_t blockchain_storage::get_current_sequence_factor_for_alt(alt_chain_type& a
|
|||
return n;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::get_pos_votes(uint64_t start_index, uint64_t end_index, vote_results& r)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_read_lock);
|
||||
if (start_index >= m_db_blocks.size() || start_index >= end_index)
|
||||
{
|
||||
//LOG_PRINT_L0("Wrong starter or end index set: start_index = " << start_index << ", end_index=" << end_index << ", expected max index " << m_db_blocks.size() - 1);
|
||||
return true;
|
||||
}
|
||||
std::map<std::string, vote_on_proposal> summary;
|
||||
|
||||
for (size_t i = start_index; i < m_db_blocks.size() && i < end_index; i++)
|
||||
{
|
||||
auto block_ptr = m_db_blocks[i];
|
||||
//only coin holders can vote
|
||||
if(!is_pos_block(block_ptr->bl))
|
||||
continue;
|
||||
r.total_pos_blocks++;
|
||||
|
||||
extra_user_data eud = AUTO_VAL_INIT(eud);
|
||||
if (!get_type_in_variant_container(block_ptr->bl.miner_tx.extra, eud))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
std::list<std::pair<std::string, bool>> votes;
|
||||
if (!currency::parse_vote(eud.buff, votes))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (const auto& v : votes)
|
||||
{
|
||||
if (v.second)
|
||||
summary[v.first].vote_1++;
|
||||
else
|
||||
summary[v.first].vote_0++;
|
||||
}
|
||||
}
|
||||
for (const auto s_entry : summary)
|
||||
{
|
||||
r.votes.push_back(s_entry.second);
|
||||
r.votes.back().proposal_name = s_entry.first;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
std::string blockchain_storage::get_blockchain_string(uint64_t start_index, uint64_t end_index) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
|
|
|||
|
|
@ -451,6 +451,7 @@ namespace currency
|
|||
void serialize(archive_t & ar, const unsigned int version);
|
||||
bool get_est_height_from_date(uint64_t date, uint64_t& res_h)const;
|
||||
|
||||
bool get_pos_votes(uint64_t start_h, uint64_t end_h, vote_results& r);
|
||||
|
||||
//debug functions
|
||||
bool validate_blockchain_prev_links(size_t last_n_blocks_to_check = 10) const;
|
||||
|
|
|
|||
|
|
@ -154,6 +154,28 @@ namespace currency
|
|||
transactions_map onboard_transactions;
|
||||
};
|
||||
|
||||
struct vote_on_proposal
|
||||
{
|
||||
std::string proposal_name;
|
||||
uint64_t vote_1;
|
||||
uint64_t vote_0;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(proposal_name)
|
||||
KV_SERIALIZE(vote_1)
|
||||
KV_SERIALIZE(vote_0)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct vote_results
|
||||
{
|
||||
uint64_t total_pos_blocks; //total pos blocks in a given range
|
||||
std::list<vote_on_proposal> votes;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(total_pos_blocks)
|
||||
KV_SERIALIZE(votes)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -214,6 +214,7 @@
|
|||
#define GUI_INTERNAL_CONFIG2 "gui_internal_config.json"
|
||||
#define GUI_IPC_MESSAGE_CHANNEL_NAME CURRENCY_NAME_BASE "_message_que"
|
||||
|
||||
#define CURRENCY_VOTING_CONFIG_DEFAULT_FILENAME "voting_config.json"
|
||||
|
||||
|
||||
#define CURRENT_TRANSACTION_CHAIN_ENTRY_ARCHIVE_VER 3
|
||||
|
|
|
|||
|
|
@ -1615,6 +1615,35 @@ namespace currency
|
|||
return timestamp;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_vote(const std::string& json_, std::list<std::pair<std::string, bool>>& votes)
|
||||
{
|
||||
//do preliminary check of text if it looks like json
|
||||
std::string::size_type pos = json_.find('{');
|
||||
if (pos == std::string::npos)
|
||||
return false;
|
||||
std::string json = json_.substr(pos);
|
||||
|
||||
epee::serialization::portable_storage ps;
|
||||
bool rs = ps.load_from_json(json);
|
||||
if (!rs)
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
auto cb = [&](const std::string& name, const epee::serialization::storage_entry& entry) {
|
||||
if (entry.type() == typeid(uint64_t))
|
||||
{
|
||||
bool vote = boost::get<uint64_t>(entry) ? true : false;
|
||||
votes.push_back(std::make_pair(epee::string_encoding::toupper(name), vote));
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
ps.enum_entries(nullptr, cb);
|
||||
return true;
|
||||
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool sign_multisig_input_in_tx(currency::transaction& tx, size_t ms_input_index, const currency::account_keys& keys, const currency::transaction& source_tx, bool *p_is_input_fully_signed /* = nullptr */)
|
||||
{
|
||||
#define LOC_CHK(cond, msg) CHECK_AND_ASSERT_MES(cond, false, msg << ", ms input index: " << ms_input_index << ", tx: " << get_transaction_hash(tx) << ", source tx: " << get_transaction_hash(source_tx))
|
||||
|
|
|
|||
|
|
@ -362,7 +362,10 @@ namespace currency
|
|||
bool fill_block_rpc_details(block_rpc_extended_info& pei_rpc, const block_extended_info& bei_chain, const crypto::hash& h);
|
||||
void append_per_block_increments_for_tx(const transaction& tx, std::unordered_map<uint64_t, uint32_t>& gindices);
|
||||
std::string get_word_from_timstamp(uint64_t timestamp, bool use_password);
|
||||
uint64_t get_timstamp_from_word(std::string word, bool& password_used, const std::string& buff);
|
||||
uint64_t get_timstamp_from_word(std::string word, bool& password_used);
|
||||
bool parse_vote(const std::string& buff, std::list<std::pair<std::string, bool>>& votes);
|
||||
|
||||
std::string generate_origin_for_htlc(const txout_htlc& htlc, const account_keys& acc_keys);
|
||||
template<class t_txin_v>
|
||||
typename std::conditional<std::is_const<t_txin_v>::value, const std::vector<txin_etc_details_v>, std::vector<txin_etc_details_v> >::type& get_txin_etc_options(t_txin_v& in)
|
||||
|
|
|
|||
|
|
@ -631,6 +631,18 @@ namespace currency
|
|||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_get_votes(const COMMAND_RPC_GET_VOTES::request& req, COMMAND_RPC_GET_VOTES::response& res, connection_context& cntx)
|
||||
{
|
||||
if (!m_core.get_blockchain_storage().get_pos_votes(req.h_start, req.h_end, res.votes))
|
||||
{
|
||||
res.status = API_RETURN_CODE_INTERNAL_ERROR;
|
||||
res.error_code = "Internal error";
|
||||
return true;
|
||||
}
|
||||
res.status = API_RETURN_CODE_OK;
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_get_main_block_details(const COMMAND_RPC_GET_BLOCK_DETAILS::request& req, COMMAND_RPC_GET_BLOCK_DETAILS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx)
|
||||
{
|
||||
if (!m_core.get_blockchain_storage().get_main_block_rpc_details(req.id, res.block_details))
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ namespace currency
|
|||
bool on_get_pool_txs_brief_details(const COMMAND_RPC_GET_POOL_TXS_BRIEF_DETAILS::request& req, COMMAND_RPC_GET_POOL_TXS_BRIEF_DETAILS::response& res, connection_context& cntx);
|
||||
bool on_get_all_pool_tx_list(const COMMAND_RPC_GET_ALL_POOL_TX_LIST::request& req, COMMAND_RPC_GET_ALL_POOL_TX_LIST::response& res, connection_context& cntx);
|
||||
bool on_get_pool_info(const COMMAND_RPC_GET_POOL_INFO::request& req, COMMAND_RPC_GET_POOL_INFO::response& res, connection_context& cntx);
|
||||
bool on_get_votes(const COMMAND_RPC_GET_VOTES::request& req, COMMAND_RPC_GET_VOTES::response& res, connection_context& cntx);
|
||||
|
||||
bool on_get_main_block_details(const COMMAND_RPC_GET_BLOCK_DETAILS::request& req, COMMAND_RPC_GET_BLOCK_DETAILS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
|
||||
bool on_get_alt_block_details(const COMMAND_RPC_GET_BLOCK_DETAILS::request& req, COMMAND_RPC_GET_BLOCK_DETAILS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
|
||||
|
|
@ -150,6 +151,7 @@ namespace currency
|
|||
MAP_JON_RPC ("get_pool_txs_brief_details", on_get_pool_txs_brief_details, COMMAND_RPC_GET_POOL_TXS_BRIEF_DETAILS)
|
||||
MAP_JON_RPC ("get_all_pool_tx_list", on_get_all_pool_tx_list, COMMAND_RPC_GET_ALL_POOL_TX_LIST)
|
||||
MAP_JON_RPC ("get_pool_info", on_get_pool_info, COMMAND_RPC_GET_POOL_INFO)
|
||||
MAP_JON_RPC ("get_votes", on_get_votes, COMMAND_RPC_GET_VOTES)
|
||||
|
||||
MAP_JON_RPC_WE("get_main_block_details", on_get_main_block_details, COMMAND_RPC_GET_BLOCK_DETAILS)
|
||||
MAP_JON_RPC_WE("get_alt_block_details", on_get_alt_block_details, COMMAND_RPC_GET_BLOCK_DETAILS)
|
||||
|
|
|
|||
|
|
@ -83,6 +83,34 @@ namespace currency
|
|||
};
|
||||
};
|
||||
|
||||
|
||||
struct COMMAND_RPC_GET_VOTES
|
||||
{
|
||||
struct request
|
||||
{
|
||||
uint64_t h_start;
|
||||
uint64_t h_end;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(h_start)
|
||||
KV_SERIALIZE(h_end)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
std::string status;
|
||||
std::string error_code;
|
||||
vote_results votes;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(error_code)
|
||||
KV_SERIALIZE(votes)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_GET_HEIGHT
|
||||
{
|
||||
struct request
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ namespace
|
|||
const command_line::arg_descriptor<std::string> arg_addr_to_compare ( "addr-to-compare", "");
|
||||
const command_line::arg_descriptor<bool> arg_disable_tor_relay ( "disable-tor-relay", "Disable TOR relay", false);
|
||||
const command_line::arg_descriptor<unsigned int> arg_set_timeout("set-timeout", "Set timeout for the wallet");
|
||||
const command_line::arg_descriptor<std::string> arg_voting_config_file("voting-config-file", "Set voting config instead of getting if from daemon", "");
|
||||
|
||||
const command_line::arg_descriptor< std::vector<std::string> > arg_command ("command", "");
|
||||
|
||||
|
|
@ -413,6 +414,7 @@ void simple_wallet::handle_command_line(const boost::program_options::variables_
|
|||
m_do_pos_mining = command_line::get_arg(vm, arg_do_pos_mining);
|
||||
m_restore_wallet = command_line::get_arg(vm, arg_restore_wallet);
|
||||
m_disable_tor = command_line::get_arg(vm, arg_disable_tor_relay);
|
||||
m_voting_config_file = command_line::get_arg(vm, arg_voting_config_file);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::try_connect_to_daemon()
|
||||
|
|
@ -433,18 +435,21 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas
|
|||
|
||||
m_wallet.reset(new tools::wallet2());
|
||||
m_wallet->callback(this->shared_from_this());
|
||||
if (!m_voting_config_file.empty())
|
||||
m_wallet->set_votes_config_path(m_voting_config_file);
|
||||
|
||||
m_wallet->set_do_rise_transfer(false);
|
||||
try
|
||||
{
|
||||
m_wallet->generate(epee::string_encoding::utf8_to_wstring(m_wallet_file), password, create_auditable_wallet);
|
||||
message_writer(epee::log_space::console_color_white, true) << "Generated new " << (create_auditable_wallet ? "AUDITABLE" : "") << " wallet: " << m_wallet->get_account().get_public_address_str();
|
||||
display_vote_info();
|
||||
std::cout << "view key: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().view_secret_key) << std::endl << std::flush;
|
||||
if (m_wallet->is_auditable())
|
||||
std::cout << "tracking seed: " << std::endl << m_wallet->get_account().get_tracking_seed() << std::endl << std::flush;
|
||||
if (m_do_not_set_date)
|
||||
m_wallet->reset_creation_time(0);
|
||||
|
||||
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
|
|
@ -465,6 +470,9 @@ bool simple_wallet::restore_wallet(const std::string& wallet_file, const std::st
|
|||
|
||||
m_wallet.reset(new tools::wallet2());
|
||||
m_wallet->callback(this->shared_from_this());
|
||||
if (!m_voting_config_file.empty())
|
||||
m_wallet->set_votes_config_path(m_voting_config_file);
|
||||
|
||||
m_wallet->set_do_rise_transfer(true);
|
||||
try
|
||||
{
|
||||
|
|
@ -473,6 +481,7 @@ bool simple_wallet::restore_wallet(const std::string& wallet_file, const std::st
|
|||
// auditable watch-only aka tracking wallet
|
||||
m_wallet->restore(epee::string_encoding::utf8_to_wstring(wallet_file), password, seed_or_tracking_seed, true, "");
|
||||
message_writer(epee::log_space::console_color_white, true) << "Tracking wallet restored: " << m_wallet->get_account().get_public_address_str();
|
||||
display_vote_info();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -509,11 +518,27 @@ bool simple_wallet::restore_wallet(const std::string& wallet_file, const std::st
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
void simple_wallet::display_vote_info()
|
||||
{
|
||||
const wallet_vote_config& votes = m_wallet->get_current_votes();
|
||||
if (votes.entries.size())
|
||||
{
|
||||
message_writer(epee::log_space::console_color_magenta, true) << "VOTING SET LOADED:";
|
||||
for (const auto& e : votes.entries)
|
||||
{
|
||||
message_writer(epee::log_space::console_color_magenta, true) << "\t\t" << e.proposal_id << "\t\t" << (e.vote?"1":"0") << "\t\t("<< e.h_start << " - " << e.h_end <<")";
|
||||
}
|
||||
}
|
||||
}
|
||||
bool simple_wallet::open_wallet(const string &wallet_file, const std::string& password)
|
||||
{
|
||||
m_wallet_file = wallet_file;
|
||||
m_wallet.reset(new tools::wallet2());
|
||||
m_wallet->callback(shared_from_this());
|
||||
if (!m_voting_config_file.empty())
|
||||
m_wallet->set_votes_config_path(m_voting_config_file);
|
||||
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
|
@ -521,6 +546,7 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa
|
|||
{
|
||||
m_wallet->load(epee::string_encoding::utf8_to_wstring(m_wallet_file), password);
|
||||
message_writer(epee::log_space::console_color_white, true) << "Opened" << (m_wallet->is_auditable() ? " auditable" : "") << (m_wallet->is_watch_only() ? " watch-only" : "") << " wallet: " << m_wallet->get_account().get_public_address_str();
|
||||
display_vote_info();
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ namespace currency
|
|||
|
||||
uint64_t get_daemon_blockchain_height(std::string& err);
|
||||
bool try_connect_to_daemon();
|
||||
void display_vote_info();
|
||||
|
||||
//----------------- i_wallet2_callback ---------------------
|
||||
virtual void on_new_block(uint64_t height, const currency::block& block) override;
|
||||
|
|
@ -172,6 +173,7 @@ namespace currency
|
|||
bool m_offline_mode;
|
||||
bool m_disable_tor;
|
||||
std::string m_restore_wallet;
|
||||
std::string m_voting_config_file;
|
||||
|
||||
epee::console_handlers_binder m_cmd_binder;
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ namespace tools
|
|||
m_pos_mint_packing_size(WALLET_DEFAULT_POS_MINT_PACKING_SIZE),
|
||||
m_current_wallet_file_size(0),
|
||||
m_use_deffered_global_outputs(false),
|
||||
m_disable_tor_relay(false)
|
||||
m_disable_tor_relay(false),
|
||||
m_votes_config_path(tools::get_default_data_dir() + "/" + CURRENCY_VOTING_CONFIG_DEFAULT_FILENAME)
|
||||
{
|
||||
m_core_runtime_config = currency::get_default_core_runtime_config();
|
||||
}
|
||||
|
|
@ -171,7 +172,7 @@ std::shared_ptr<wallet2::transaction_wallet_info> wallet2::transform_value_to_pt
|
|||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::init(const std::string& daemon_address)
|
||||
{
|
||||
m_miner_text_info = PROJECT_VERSION_LONG;
|
||||
//m_miner_text_info = PROJECT_VERSION_LONG;
|
||||
m_core_proxy->set_connection_addr(daemon_address);
|
||||
m_core_proxy->check_connection();
|
||||
}
|
||||
|
|
@ -2650,6 +2651,19 @@ bool wallet2::check_connection()
|
|||
return m_core_proxy->check_connection();
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::set_votes_config_path(const std::string& path_to_config_file/* = tools::get_default_data_dir() + "\voting_config.json"*/)
|
||||
{
|
||||
m_votes_config_path = path_to_config_file;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::load_votes_config()
|
||||
{
|
||||
if (boost::filesystem::exists(m_votes_config_path))
|
||||
{
|
||||
epee::serialization::load_t_from_json_file(m_votes_config, m_votes_config_path);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::load(const std::wstring& wallet_, const std::string& password)
|
||||
{
|
||||
clear();
|
||||
|
|
@ -2720,6 +2734,7 @@ void wallet2::load(const std::wstring& wallet_, const std::string& password)
|
|||
);
|
||||
WLT_LOG_L1("[LOADING]Blockchain shortener state: " << ENDL << m_chain.get_internal_state_text());
|
||||
|
||||
load_votes_config();
|
||||
|
||||
WLT_LOG_L1("(after loading: pending_key_images: " << m_pending_key_images.size() << ", pki file elements: " << m_pending_key_images_file_container.size() << ", tx_keys: " << m_tx_keys.size() << ")");
|
||||
|
||||
|
|
@ -3599,7 +3614,30 @@ bool wallet2::build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request&
|
|||
{
|
||||
return build_minted_block(req, rsp, m_account.get_public_address(), new_block_expected_height);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
std::string wallet2::get_extra_text_for_block(uint64_t new_block_expected_height)
|
||||
{
|
||||
size_t entries_voted = 0;
|
||||
std::string extra_text = "{";
|
||||
for (const auto& e : m_votes_config.entries)
|
||||
{
|
||||
if (e.h_start <= new_block_expected_height && e.h_end >= new_block_expected_height)
|
||||
{
|
||||
//do vote for/against this
|
||||
if (entries_voted != 0)
|
||||
extra_text += ",";
|
||||
extra_text += "\"";
|
||||
extra_text += e.proposal_id;
|
||||
extra_text += "\":";
|
||||
extra_text += e.vote ? "1" : "0";
|
||||
entries_voted++;
|
||||
}
|
||||
}
|
||||
if (!entries_voted)
|
||||
extra_text = "";
|
||||
return extra_text;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool wallet2::build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request& req,
|
||||
const currency::COMMAND_RPC_SCAN_POS::response& rsp,
|
||||
const currency::account_public_address& miner_address,
|
||||
|
|
@ -3617,7 +3655,7 @@ bool wallet2::build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request&
|
|||
tmpl_req.pos_block = true;
|
||||
tmpl_req.pos_amount = req.pos_entries[rsp.index].amount;
|
||||
tmpl_req.pos_index = req.pos_entries[rsp.index].index;
|
||||
tmpl_req.extra_text = m_miner_text_info;
|
||||
tmpl_req.extra_text = get_extra_text_for_block(new_block_expected_height); // m_miner_text_info;
|
||||
tmpl_req.stake_unlock_time = req.pos_entries[rsp.index].stake_unlock_time;
|
||||
|
||||
// mark stake source as spent and make sure it will be restored in case of error
|
||||
|
|
|
|||
|
|
@ -541,8 +541,7 @@ namespace tools
|
|||
void update_offer_by_id(const crypto::hash& tx_id, uint64_t of_ind, const bc_services::offer_details_ex& od, currency::transaction& res_tx);
|
||||
void request_alias_registration(currency::extra_alias_entry& ai, currency::transaction& res_tx, uint64_t fee, uint64_t reward, const crypto::secret_key& authority_key = currency::null_skey);
|
||||
void request_alias_update(currency::extra_alias_entry& ai, currency::transaction& res_tx, uint64_t fee, uint64_t reward);
|
||||
bool check_available_sources(std::list<uint64_t>& amounts);
|
||||
|
||||
bool check_available_sources(std::list<uint64_t>& amounts);
|
||||
|
||||
bool set_core_proxy(const std::shared_ptr<i_core_proxy>& proxy);
|
||||
void set_pos_mint_packing_size(uint64_t new_size);
|
||||
|
|
@ -817,6 +816,7 @@ namespace tools
|
|||
bool get_pos_entries(currency::COMMAND_RPC_SCAN_POS::request& req);
|
||||
bool build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request& req, const currency::COMMAND_RPC_SCAN_POS::response& rsp, uint64_t new_block_expected_height = UINT64_MAX);
|
||||
bool build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request& req, const currency::COMMAND_RPC_SCAN_POS::response& rsp, const currency::account_public_address& miner_address, uint64_t new_block_expected_height = UINT64_MAX);
|
||||
std::string get_extra_text_for_block(uint64_t new_block_expected_height);
|
||||
bool reset_history();
|
||||
bool is_transfer_unlocked(const transfer_details& td) const;
|
||||
bool is_transfer_unlocked(const transfer_details& td, bool for_pos_mining, uint64_t& stake_lock_time) const;
|
||||
|
|
@ -879,6 +879,9 @@ namespace tools
|
|||
void redeem_htlc(const crypto::hash& htlc_tx_id, const std::string& origin, currency::transaction& result_tx);
|
||||
void redeem_htlc(const crypto::hash& htlc_tx_id, const std::string& origin);
|
||||
bool check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& origin, crypto::hash& redeem_tx_id);
|
||||
|
||||
void set_votes_config_path(const std::string& path_to_config_file);
|
||||
const wallet_vote_config& get_current_votes() { return m_votes_config; }
|
||||
private:
|
||||
|
||||
// -------- t_transport_state_notifier ------------------------------------------------
|
||||
|
|
@ -958,10 +961,9 @@ private:
|
|||
bool handle_cancel_proposal(wallet_public::wallet_transfer_info& wti, const bc_services::escrow_cancel_templates_body& ectb, const std::vector<currency::payload_items_v>& decrypted_attach);
|
||||
bool handle_expiration_list(uint64_t tx_expiration_ts_median);
|
||||
void handle_contract_expirations(uint64_t tx_expiration_ts_median);
|
||||
|
||||
void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const wallet_public::wallet_transfer_info& wti) const;
|
||||
void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const std::string& reason = "internal intention") const;
|
||||
|
||||
void load_votes_config();
|
||||
|
||||
const construct_tx_param& get_default_construct_tx_param();
|
||||
|
||||
|
|
@ -1073,6 +1075,9 @@ private:
|
|||
mutable uint64_t m_current_wallet_file_size;
|
||||
bool m_use_deffered_global_outputs;
|
||||
bool m_disable_tor_relay;
|
||||
|
||||
std::string m_votes_config_path;
|
||||
wallet_vote_config m_votes_config;
|
||||
//this needed to access wallets state in coretests, for creating abnormal blocks and tranmsactions
|
||||
friend class test_generator;
|
||||
|
||||
|
|
|
|||
|
|
@ -1147,6 +1147,34 @@ namespace wallet_public
|
|||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct wallet_vote_config_entry
|
||||
{
|
||||
std::string proposal_id;
|
||||
uint64_t h_start;
|
||||
uint64_t h_end;
|
||||
bool vote;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(proposal_id)
|
||||
KV_SERIALIZE(h_start)
|
||||
KV_SERIALIZE(h_end)
|
||||
KV_SERIALIZE(vote)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
|
||||
};
|
||||
|
||||
struct wallet_vote_config
|
||||
{
|
||||
std::vector<wallet_vote_config_entry> entries;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(entries)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
||||
inline std::string get_escrow_contract_state_name(uint32_t state)
|
||||
{
|
||||
switch (state)
|
||||
|
|
|
|||
|
|
@ -956,6 +956,9 @@ std::string wallets_manager::open_wallet(const std::wstring& path, const std::st
|
|||
LOG_ERROR("Unexpected location reached");
|
||||
#endif
|
||||
}
|
||||
|
||||
w->set_votes_config_path(m_data_dir + "/" + CURRENCY_VOTING_CONFIG_DEFAULT_FILENAME);
|
||||
|
||||
|
||||
std::string return_code = API_RETURN_CODE_OK;
|
||||
while (true)
|
||||
|
|
@ -970,6 +973,7 @@ std::string wallets_manager::open_wallet(const std::wstring& path, const std::st
|
|||
//w->get_unconfirmed_transfers(owr.recent_history.unconfirmed);
|
||||
w->get_unconfirmed_transfers(owr.recent_history.history, exclude_mining_txs);
|
||||
owr.wallet_local_bc_size = w->get_blockchain_current_size();
|
||||
|
||||
//workaround for missed fee
|
||||
//owr.seed = w->get_account().get_seed_phrase();
|
||||
break;
|
||||
|
|
@ -1061,6 +1065,7 @@ std::string wallets_manager::generate_wallet(const std::wstring& path, const std
|
|||
{
|
||||
std::shared_ptr<tools::wallet2> w(new tools::wallet2());
|
||||
w->set_use_deffered_global_outputs(m_use_deffered_global_outputs);
|
||||
w->set_votes_config_path(m_data_dir + "/" + CURRENCY_VOTING_CONFIG_DEFAULT_FILENAME);
|
||||
owr.wallet_id = m_wallet_id_counter++;
|
||||
w->callback(std::shared_ptr<tools::i_wallet2_callback>(new i_wallet_to_i_backend_adapter(this, owr.wallet_id)));
|
||||
if (m_remote_node_mode)
|
||||
|
|
@ -1167,6 +1172,7 @@ std::string wallets_manager::restore_wallet(const std::wstring& path, const std:
|
|||
{
|
||||
std::shared_ptr<tools::wallet2> w(new tools::wallet2());
|
||||
w->set_use_deffered_global_outputs(m_use_deffered_global_outputs);
|
||||
w->set_votes_config_path(m_data_dir + "/" + CURRENCY_VOTING_CONFIG_DEFAULT_FILENAME);
|
||||
owr.wallet_id = m_wallet_id_counter++;
|
||||
w->callback(std::shared_ptr<tools::i_wallet2_callback>(new i_wallet_to_i_backend_adapter(this, owr.wallet_id)));
|
||||
if (m_remote_node_mode)
|
||||
|
|
|
|||
26
tests/unit_tests/votes_tests.cpp
Normal file
26
tests/unit_tests/votes_tests.cpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) 2012-2014 The Zano developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "misc_language.h"
|
||||
#include "currency_core/currency_format_utils.h"
|
||||
|
||||
|
||||
TEST(governance_testig, governance_tests_1)
|
||||
{
|
||||
std::string vote = "{\"ZGP11\":1,\"ZGP23\":0}";
|
||||
|
||||
std::list<std::pair<std::string, bool>> votes;
|
||||
currency::parse_vote(vote, votes);
|
||||
ASSERT_TRUE(votes.size() == 2);
|
||||
ASSERT_TRUE(votes.begin()->first == "ZGP11");
|
||||
ASSERT_TRUE(votes.begin()->second == true);
|
||||
ASSERT_TRUE((++votes.begin())->first == "ZGP23");
|
||||
ASSERT_TRUE((++votes.begin())->second == false);
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue