Fix assigning the last voter as the deregistration voter 7 times (#157)

This commit is contained in:
Doyle 2018-08-16 16:28:12 +10:00 committed by jcktm
parent affda24c32
commit f3b43dd8c3
8 changed files with 39 additions and 12 deletions

View file

@ -38,6 +38,7 @@ namespace cryptonote
{
bool m_verification_failed;
bool m_invalid_block_height;
bool m_duplicate_voters;
bool m_voters_quorum_index_out_of_bounds;
bool m_service_node_index_out_of_bounds;
bool m_signature_not_valid;

View file

@ -3030,7 +3030,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
return false;
}
if (!loki::service_node_deregister::verify_deregister(deregister, tvc.m_vote_ctx, *quorum_state))
if (!loki::service_node_deregister::verify_deregister(nettype(), deregister, tvc.m_vote_ctx, *quorum_state))
{
tvc.m_verifivation_failed = true;
MERROR_VER("tx " << get_transaction_hash(tx) << ": version 3 deregister_tx could not be completely verified.");

View file

@ -288,6 +288,7 @@ namespace cryptonote
const bool testnet = command_line::get_arg(vm, arg_testnet_on);
const bool stagenet = command_line::get_arg(vm, arg_stagenet_on);
m_nettype = testnet ? TESTNET : stagenet ? STAGENET : MAINNET;
m_deregister_vote_pool.m_nettype = m_nettype;
}
m_config_folder = command_line::get_arg(vm, arg_data_dir);

View file

@ -126,7 +126,10 @@ namespace service_nodes
LOG_ERROR("block height was invalid: " << vote.block_height);
if (vvc.m_voters_quorum_index_out_of_bounds)
LOG_ERROR("voters quorum index specified out of bounds: " << vote.voters_quorum_index);
LOG_ERROR("voters quorum index specified was out of bounds: " << vote.voters_quorum_index);
if (vvc.m_duplicate_voters)
LOG_ERROR("voters index was duplicated: " << vote.voters_quorum_index);
if (vvc.m_service_node_index_out_of_bounds)
LOG_ERROR("service node index specified out of bounds: " << vote.service_node_index);

View file

@ -89,7 +89,7 @@ namespace loki
return true;
}
static bool verify_votes_helper(const cryptonote::tx_extra_service_node_deregister& deregister,
static bool verify_votes_helper(cryptonote::network_type nettype, const cryptonote::tx_extra_service_node_deregister& deregister,
cryptonote::vote_verification_context &vvc,
const service_nodes::quorum_state &quorum_state)
{
@ -101,6 +101,7 @@ namespace loki
}
const std::vector<crypto::public_key>& quorum = quorum_state.quorum_nodes;
std::vector<int8_t> quorum_set;
std::vector<std::pair<crypto::public_key, crypto::signature>> keys_and_sigs;
for (const cryptonote::tx_extra_service_node_deregister::vote& vote : deregister.votes)
@ -112,6 +113,21 @@ namespace loki
return false;
}
if (nettype == cryptonote::TESTNET && deregister.block_height < 6200)
{
// TODO(doyle): Remove on next testnet re-launch, also. Can remove nettype param until next fork I guess.
}
else
{
quorum_set.resize(quorum.size());
if (++quorum_set[vote.voters_quorum_index] > 1)
{
vvc.m_duplicate_voters = true;
LOG_PRINT_L1("Voter quorum index is duplicated: " << vote.voters_quorum_index << ", expected to be in range of: [0, " << quorum.size() << "]");
return false;
}
}
keys_and_sigs.push_back(std::make_pair(quorum[vote.voters_quorum_index], vote.signature));
}
@ -125,7 +141,7 @@ namespace loki
return r;
}
bool service_node_deregister::verify_deregister(const cryptonote::tx_extra_service_node_deregister& deregister,
bool service_node_deregister::verify_deregister(cryptonote::network_type nettype, const cryptonote::tx_extra_service_node_deregister& deregister,
cryptonote::vote_verification_context &vvc,
const service_nodes::quorum_state &quorum_state)
{
@ -136,18 +152,18 @@ namespace loki
return false;
}
bool result = verify_votes_helper(deregister, vvc, quorum_state);
bool result = verify_votes_helper(nettype, deregister, vvc, quorum_state);
return result;
}
bool service_node_deregister::verify_vote(const vote& v, cryptonote::vote_verification_context &vvc,
bool service_node_deregister::verify_vote(cryptonote::network_type nettype, const vote& v, cryptonote::vote_verification_context &vvc,
const service_nodes::quorum_state &quorum_state)
{
cryptonote::tx_extra_service_node_deregister deregister;
deregister.block_height = v.block_height;
deregister.service_node_index = v.service_node_index;
deregister.votes.push_back(cryptonote::tx_extra_service_node_deregister::vote{ v.signature, v.voters_quorum_index });
return verify_votes_helper(deregister, vvc, quorum_state);
return verify_votes_helper(nettype, deregister, vvc, quorum_state);
}
void deregister_vote_pool::set_relayed(const std::vector<service_node_deregister::vote>& votes)
@ -207,7 +223,7 @@ namespace loki
const service_nodes::quorum_state &quorum_state,
cryptonote::transaction &tx)
{
if (!service_node_deregister::verify_vote(new_vote, vvc, quorum_state))
if (!service_node_deregister::verify_vote(m_nettype, new_vote, vvc, quorum_state))
{
LOG_PRINT_L1("Signature verification failed for deregister vote");
return false;
@ -248,8 +264,8 @@ namespace loki
for (const auto& entry : *deregister_votes)
{
cryptonote::tx_extra_service_node_deregister::vote tx_vote = {};
tx_vote.signature = new_vote.signature;
tx_vote.voters_quorum_index = new_vote.voters_quorum_index;
tx_vote.signature = entry.signature;
tx_vote.voters_quorum_index = entry.voters_quorum_index;
deregister.votes.push_back(tx_vote);
}

View file

@ -67,11 +67,11 @@ namespace loki
bool verify_vote_signature (uint64_t block_height, uint32_t service_node_index, crypto::public_key p, crypto::signature s);
bool verify_votes_signature(uint64_t block_height, uint32_t service_node_index, const std::vector<std::pair<crypto::public_key, crypto::signature>>& keys_and_sigs);
bool verify_deregister(const cryptonote::tx_extra_service_node_deregister& deregister,
bool verify_deregister(cryptonote::network_type nettype, const cryptonote::tx_extra_service_node_deregister& deregister,
cryptonote::vote_verification_context& vvc,
const service_nodes::quorum_state &quorum);
bool verify_vote(const vote& v, cryptonote::vote_verification_context &vvc,
bool verify_vote(cryptonote::network_type nettype, const vote& v, cryptonote::vote_verification_context &vvc,
const service_nodes::quorum_state &quorum);
};
@ -92,6 +92,8 @@ namespace loki
void remove_used_votes (std::vector<cryptonote::transaction> const &txs);
std::vector<service_node_deregister::vote> get_relayable_votes () const;
cryptonote::network_type m_nettype = cryptonote::UNDEFINED;
private:
struct deregister
{

View file

@ -786,6 +786,8 @@ namespace cryptonote
const vote_verification_context &vvc = tvc.m_vote_ctx;
if ((res.invalid_block_height = vvc.m_invalid_block_height))
add_reason(res.reason, "block height was invalid");
if ((res.duplicate_voters = vvc.m_duplicate_voters))
add_reason(res.reason, "voters index was duplicated");
if ((res.voters_quorum_index_out_of_bounds = vvc.m_voters_quorum_index_out_of_bounds))
add_reason(res.reason, "voters quorum index specified out of bounds");
if ((res.service_node_index_out_of_bounds = vvc.m_service_node_index_out_of_bounds))

View file

@ -886,6 +886,7 @@ namespace cryptonote
bool invalid_block_height;
bool voters_quorum_index_out_of_bounds;
bool duplicate_voters;
bool service_node_index_out_of_bounds;
bool signature_not_valid;
bool not_enough_votes;
@ -906,6 +907,7 @@ namespace cryptonote
KV_SERIALIZE(invalid_block_height)
KV_SERIALIZE(voters_quorum_index_out_of_bounds)
KV_SERIALIZE(duplicate_voters)
KV_SERIALIZE(service_node_index_out_of_bounds)
KV_SERIALIZE(signature_not_valid)
KV_SERIALIZE(not_enough_votes)