Add batch votes verification (#1377)

This commit is contained in:
SergiySW 2018-11-15 01:51:40 +03:00 committed by Roy Keene
commit a291bc8f91
2 changed files with 44 additions and 4 deletions

View file

@ -811,13 +811,14 @@ void rai::vote_processor::process_loop ()
}
active = true;
lock.unlock ();
verify_votes (votes_l);
{
std::unique_lock<std::mutex> active_single_lock (node.active.mutex);
auto transaction (node.store.tx_begin_read ());
uint64_t count (1);
for (auto & i : votes_l)
{
vote_blocking (transaction, i.first, i.second);
vote_blocking (transaction, i.first, i.second, true);
// Free active_transactions mutex each 100 processed votes
if (count % 100 == 0)
{
@ -867,13 +868,51 @@ void rai::vote_processor::vote (std::shared_ptr<rai::vote> vote_a, rai::endpoint
}
}
void rai::vote_processor::verify_votes (std::deque<std::pair<std::shared_ptr<rai::vote>, rai::endpoint>> & votes_a)
{
auto size (votes_a.size ());
std::vector<unsigned char const *> messages;
messages.reserve (size);
std::vector<rai::uint256_union> hashes;
hashes.reserve (size);
std::vector<size_t> lengths (size, sizeof (rai::uint256_union));
std::vector<unsigned char const *> pub_keys;
pub_keys.reserve (size);
std::vector<unsigned char const *> signatures;
signatures.reserve (size);
std::vector<int> verifications;
verifications.resize (size);
for (auto & vote : votes_a)
{
hashes.push_back (vote.first->hash ());
messages.push_back (hashes.back ().bytes.data ());
pub_keys.push_back (vote.first->account.bytes.data ());
signatures.push_back (vote.first->signature.bytes.data ());
}
/* Verifications is vector if signatures check results
validate_message_batch returing "true" if there are at least 1 invalid signature */
rai::validate_message_batch (messages.data (), lengths.data (), pub_keys.data (), signatures.data (), size, verifications.data ());
std::remove_reference_t<decltype (votes_a)> result;
auto i (0);
for (auto & vote : votes_a)
{
assert (verifications[i] == 1 || verifications[i] == 0);
if (verifications[i] == 1)
{
result.push_back (vote);
}
++i;
}
votes_a.swap (result);
}
// node.active.mutex lock required
rai::vote_code rai::vote_processor::vote_blocking (rai::transaction const & transaction_a, std::shared_ptr<rai::vote> vote_a, rai::endpoint endpoint_a)
rai::vote_code rai::vote_processor::vote_blocking (rai::transaction const & transaction_a, std::shared_ptr<rai::vote> vote_a, rai::endpoint endpoint_a, bool validated)
{
assert (endpoint_a.address ().is_v6 ());
assert (!node.active.mutex.try_lock ());
auto result (rai::vote_code::invalid);
if (!vote_a->validate ())
if (validated || !vote_a->validate ())
{
auto max_vote (node.store.vote_max (transaction_a, vote_a));
result = rai::vote_code::replay;

View file

@ -342,7 +342,8 @@ public:
vote_processor (rai::node &);
void vote (std::shared_ptr<rai::vote>, rai::endpoint);
// node.active.mutex lock required
rai::vote_code vote_blocking (rai::transaction const &, std::shared_ptr<rai::vote>, rai::endpoint);
rai::vote_code vote_blocking (rai::transaction const &, std::shared_ptr<rai::vote>, rai::endpoint, bool = false);
void verify_votes (std::deque<std::pair<std::shared_ptr<rai::vote>, rai::endpoint>> &);
void flush ();
rai::node & node;
void stop ();