From 30a41c2ab12193a715eeb2f34cbf347bf542487d Mon Sep 17 00:00:00 2001 From: wowario Date: Sun, 20 Jun 2021 08:17:43 +0300 Subject: [PATCH] vote by block --- src/cryptonote_basic/cryptonote_basic.h | 4 +++ .../cryptonote_boost_serialization.h | 1 + src/cryptonote_basic/miner.cpp | 30 ++++++++++++++++ src/cryptonote_basic/miner.h | 2 ++ src/cryptonote_core/blockchain.cpp | 6 ++++ src/daemon/rpc_command_executor.cpp | 1 + src/rpc/core_rpc_server.cpp | 2 ++ src/rpc/core_rpc_server_commands_defs.h | 4 ++- src/rpc/daemon_handler.cpp | 1 + src/rpc/message_data_structs.h | 1 + src/serialization/json_object.cpp | 4 +++ utils/votes.pl | 34 +++++++++++++++++++ 12 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 utils/votes.pl diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h index 4cc66c7c3..6f9bf4741 100644 --- a/src/cryptonote_basic/cryptonote_basic.h +++ b/src/cryptonote_basic/cryptonote_basic.h @@ -451,6 +451,7 @@ namespace cryptonote crypto::hash prev_id; uint32_t nonce; crypto::signature signature; + uint16_t vote; BEGIN_SERIALIZE() VARINT_FIELD(major_version) @@ -459,7 +460,10 @@ namespace cryptonote FIELD(prev_id) FIELD(nonce) if (major_version >= BLOCK_HEADER_MINER_SIG) + { FIELD(signature) + FIELD(vote) + } END_SERIALIZE() }; diff --git a/src/cryptonote_basic/cryptonote_boost_serialization.h b/src/cryptonote_basic/cryptonote_boost_serialization.h index 524df1f9f..e8521eeb1 100644 --- a/src/cryptonote_basic/cryptonote_boost_serialization.h +++ b/src/cryptonote_basic/cryptonote_boost_serialization.h @@ -188,6 +188,7 @@ namespace boost if (b.major_version >= BLOCK_HEADER_MINER_SIG) { a & b.signature; + a & b.vote; } //------------------ a & b.miner_tx; diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp index a6df0d953..d3c40d066 100644 --- a/src/cryptonote_basic/miner.cpp +++ b/src/cryptonote_basic/miner.cpp @@ -100,6 +100,7 @@ namespace cryptonote const command_line::arg_descriptor arg_bg_mining_idle_threshold_percentage = {"bg-mining-idle-threshold", "Specify minimum avg idle percentage over lookback interval", miner::BACKGROUND_MINING_DEFAULT_IDLE_THRESHOLD_PERCENTAGE, true}; const command_line::arg_descriptor arg_bg_mining_miner_target_percentage = {"bg-mining-miner-target", "Specify maximum percentage cpu use by miner(s)", miner::BACKGROUND_MINING_DEFAULT_MINING_TARGET_PERCENTAGE, true}; const command_line::arg_descriptor arg_spendkey = {"spendkey", "Specify secret spend key used for mining", "", true}; + const command_line::arg_descriptor arg_vote = {"vote", "Vote for proposals.", "", true}; } @@ -293,6 +294,7 @@ namespace cryptonote command_line::add_arg(desc, arg_bg_mining_idle_threshold_percentage); command_line::add_arg(desc, arg_bg_mining_miner_target_percentage); command_line::add_arg(desc, arg_spendkey); + command_line::add_arg(desc, arg_vote); } //----------------------------------------------------------------------------------------------------- bool miner::init(const boost::program_options::variables_map& vm, network_type nettype) @@ -308,6 +310,25 @@ namespace cryptonote m_spendkey = spendkey; m_viewkey = viewkey; } + if(!command_line::has_arg(vm, arg_vote)) + { + m_int_vote = 0; + } else { + m_vote = command_line::get_arg(vm, arg_vote); + if(m_vote != "yes" && m_vote != "no") + { + LOG_ERROR("Voting format error, only a \"yes\" or \"no\" response is accepted"); + return false; + } + if(m_vote == "yes") + { + m_int_vote = 1; + } + if(m_vote == "no") + { + m_int_vote = 2; + } + } if(command_line::has_arg(vm, arg_extra_messages)) { std::string buff; @@ -605,6 +626,7 @@ namespace cryptonote crypto::generate_signature(sig_data, eph_pub_key, eph_secret_key, signature); // amend signature to block header before PoW hashing b.signature = signature; + b.vote = m_int_vote; } crypto::hash h; @@ -642,6 +664,14 @@ namespace cryptonote " //@@@@@@@@@@@@@@@@@// \n" << ENDL); MGINFO_GREEN("Awesome, you won a block reward!\n" << get_block_hash(b) << " at height " << height); + if (b.vote == 1) + { + MGINFO_GREEN("Your \"YES\" vote has been cast."); + } + if (b.vote == 2) + { + MGINFO_GREEN("Your \"NO\" vote has been cast."); + } cryptonote::block_verification_context bvc; if(!m_phandler->handle_block_found(b, bvc) || !bvc.m_added_to_main_chain) { diff --git a/src/cryptonote_basic/miner.h b/src/cryptonote_basic/miner.h index 9faf272ef..082156a05 100644 --- a/src/cryptonote_basic/miner.h +++ b/src/cryptonote_basic/miner.h @@ -138,6 +138,8 @@ namespace cryptonote account_public_address m_mine_address; crypto::secret_key m_spendkey; crypto::secret_key m_viewkey; + std::string m_vote; + uint16_t m_int_vote; epee::math_helper::once_a_time_seconds<5> m_update_block_template_interval; epee::math_helper::once_a_time_seconds<2> m_update_merge_hr_interval; epee::math_helper::once_a_time_seconds<1> m_autodetect_interval; diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 4ed31fbba..4677e4d1c 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1391,6 +1391,11 @@ bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height, MWARNING("Wrong txout type"); return false; } + if (b.vote > 2) + { + MWARNING("Vote integer must be either 0, 1, or 2"); + return false; + } // keccak hash block header data and check miner signature // if signature is invalid, reject block crypto::hash sig_data = get_sig_data(b); @@ -1402,6 +1407,7 @@ bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height, return false; } else { LOG_PRINT_L1("Miner signature is good"); + LOG_PRINT_L1("Vote: " << b.vote); } } diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index f0147ee44..c03fe77dc 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -94,6 +94,7 @@ namespace { void print_block_header(cryptonote::block_header_response const & header) { tools::success_msg_writer() + << "vote: " << header.vote << std::endl << "timestamp: " << boost::lexical_cast(header.timestamp) << " (" << tools::get_human_readable_timestamp(header.timestamp) << ")" << std::endl << "previous hash: " << header.prev_hash << std::endl << "nonce: " << boost::lexical_cast(header.nonce) << std::endl diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index fea0084c0..0b1b7803e 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1937,6 +1937,7 @@ namespace cryptonote if (b.major_version >= BLOCK_HEADER_MINER_SIG) { b.signature = {}; + b.vote = 0; } crypto::hash seed_hash = crypto::null_hash; if (b.major_version >= RX_BLOCK_VERSION && !epee::string_tools::hex_to_pod(template_res.seed_hash, seed_hash)) @@ -1976,6 +1977,7 @@ namespace cryptonote bool core_rpc_server::fill_block_header_response(const block& blk, bool orphan_status, uint64_t height, const crypto::hash& hash, block_header_response& response, bool fill_pow_hash) { PERF_TIMER(fill_block_header_response); + response.vote = blk.vote; response.major_version = blk.major_version; response.minor_version = blk.minor_version; response.timestamp = blk.timestamp; diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 9f7a6bf9e..1e593f0ea 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -88,7 +88,7 @@ namespace cryptonote // advance which version they will stop working with // Don't go over 32767 for any of these #define CORE_RPC_VERSION_MAJOR 3 -#define CORE_RPC_VERSION_MINOR 5 +#define CORE_RPC_VERSION_MINOR 8 #define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor)) #define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR) @@ -1010,6 +1010,7 @@ namespace cryptonote std::string pow_hash; uint64_t long_term_weight; std::string miner_tx_hash; + uint16_t vote; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(major_version) @@ -1034,6 +1035,7 @@ namespace cryptonote KV_SERIALIZE(pow_hash) KV_SERIALIZE_OPT(long_term_weight, (uint64_t)0) KV_SERIALIZE(miner_tx_hash) + KV_SERIALIZE(vote) END_KV_SERIALIZE_MAP() }; diff --git a/src/rpc/daemon_handler.cpp b/src/rpc/daemon_handler.cpp index 382f53697..44af64f15 100644 --- a/src/rpc/daemon_handler.cpp +++ b/src/rpc/daemon_handler.cpp @@ -898,6 +898,7 @@ namespace rpc if (b.major_version >= BLOCK_HEADER_MINER_SIG) { header.signature = b.signature; + header.vote = b.vote; } header.prev_id = b.prev_id; diff --git a/src/rpc/message_data_structs.h b/src/rpc/message_data_structs.h index d5ce770f5..ac6568d1a 100644 --- a/src/rpc/message_data_structs.h +++ b/src/rpc/message_data_structs.h @@ -165,6 +165,7 @@ namespace rpc crypto::hash prev_id; uint32_t nonce; crypto::signature signature; + uint16_t vote; uint64_t height; uint64_t depth; crypto::hash hash; diff --git a/src/serialization/json_object.cpp b/src/serialization/json_object.cpp index ebf4c3d32..e5bad77bf 100644 --- a/src/serialization/json_object.cpp +++ b/src/serialization/json_object.cpp @@ -313,6 +313,7 @@ void toJsonValue(rapidjson::Writer& dest, const cryptonote::b INSERT_INTO_JSON_OBJECT(dest, prev_id, b.prev_id); INSERT_INTO_JSON_OBJECT(dest, nonce, b.nonce); INSERT_INTO_JSON_OBJECT(dest, signature, b.signature); + INSERT_INTO_JSON_OBJECT(dest, vote, b.vote); INSERT_INTO_JSON_OBJECT(dest, miner_tx, b.miner_tx); INSERT_INTO_JSON_OBJECT(dest, tx_hashes, b.tx_hashes); @@ -333,6 +334,7 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::block& b) GET_FROM_JSON_OBJECT(val, b.prev_id, prev_id); GET_FROM_JSON_OBJECT(val, b.nonce, nonce); GET_FROM_JSON_OBJECT(val, b.signature, signature); + GET_FROM_JSON_OBJECT(val, b.vote, vote); GET_FROM_JSON_OBJECT(val, b.miner_tx, miner_tx); GET_FROM_JSON_OBJECT(val, b.tx_hashes, tx_hashes); } @@ -1048,6 +1050,7 @@ void toJsonValue(rapidjson::Writer& dest, const cryptonote::r { dest.StartObject(); + INSERT_INTO_JSON_OBJECT(dest, vote, response.vote); INSERT_INTO_JSON_OBJECT(dest, major_version, response.major_version); INSERT_INTO_JSON_OBJECT(dest, minor_version, response.minor_version); INSERT_INTO_JSON_OBJECT(dest, timestamp, response.timestamp); @@ -1069,6 +1072,7 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::BlockHeaderResp throw WRONG_TYPE("json object"); } + GET_FROM_JSON_OBJECT(val, response.vote, vote); GET_FROM_JSON_OBJECT(val, response.major_version, major_version); GET_FROM_JSON_OBJECT(val, response.minor_version, minor_version); GET_FROM_JSON_OBJECT(val, response.timestamp, timestamp); diff --git a/utils/votes.pl b/utils/votes.pl new file mode 100644 index 000000000..8cd37a2d3 --- /dev/null +++ b/utils/votes.pl @@ -0,0 +1,34 @@ +# Script gets votes for a block range. +# Run: perl votes.pl 60 300 + +$IP='127.0.0.1:11181'; + +$begin=$ARGV[0]; +if ($#ARGV == 1 ) { $end=$ARGV[1]; } + +open (F,">vote.txt"); +for ($i=$begin; $i<$end; $i++) { + $k=qq(-d '{"params":{"height":$i},"jsonrpc":"2.0","id":"test","method":"get_block_header_by_height"}' -H 'Content-Type: application/json'); + $k=`curl -s -X POST http://$IP/json_rpc $k`; + $k=~/"vote"\D+(\d+)/sg; + $v=$1; + print F "$v "; +} +close F; + +$s = do{local(@ARGV,$/)="vote.txt";<>}; +$yes = "1"; +$count1 = () = $s =~ /\Q$yes/g; +print "$count1 votes for yes\n"; +$no = "2"; +$count2 = () = $s =~ /\Q$no/g; +print "$count2 votes for no\n"; +$abs = "0"; +$count0 = () = $s =~ /\Q$abs/g; +print "$count0 abstained\n"; + +if ($count1 > $count2) { + print "Computer says... Yes!\n"; +} else { + print "Computer says... No!\n"; +} \ No newline at end of file