blockchain: set verification failed in subsystem, check validator bit masks

This commit is contained in:
Doyle 2020-06-23 12:35:30 +10:00
parent 0abb47848a
commit 80552293a3
3 changed files with 20 additions and 5 deletions

View File

@ -4261,12 +4261,14 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
if (!m_service_node_list.block_added(bl, only_txs, checkpoint))
{
MERROR("Failed to add block to Service Node List.");
bvc.m_verifivation_failed = true;
return false;
}
if (!m_lns_db.add_block(bl, only_txs))
{
MERROR("Failed to add block to LNS DB.");
bvc.m_verifivation_failed = true;
return false;
}
@ -4275,6 +4277,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
if (!hook->block_added(bl, only_txs, checkpoint))
{
MERROR("Block added hook signalled failure");
bvc.m_verifivation_failed = true;
return false;
}
}

View File

@ -1287,13 +1287,23 @@ namespace service_nodes
return false;
}
if ((block.pulse.validator_participation_bits & (~service_nodes::PULSE_VALIDATOR_PARTICIPATION_MASK)) > 0)
{
auto mask = std::bitset<sizeof(service_nodes::PULSE_VALIDATOR_PARTICIPATION_MASK) * 8>(service_nodes::PULSE_VALIDATOR_PARTICIPATION_MASK);
LOG_PRINT_L1("Pulse block specifies validator participation bits out of bounds. Expected the bit mask " << mask << "\n" << dump_pulse_block_data(block, quorum.get()));
return false;
}
for (cryptonote::pulse_verification const &verification : block.verification)
{
if (verification.quorum_index >= quorum->validators.size())
{
LOG_PRINT_L1("Received pulse signature with quorum index out of array bounds " << static_cast<int>(verification.quorum_index) << "\n" << dump_pulse_block_data(block, quorum.get()));
return false;
}
uint16_t mask = 1 << verification.quorum_index;
if ((block.pulse.validator_participation_bits & mask) == 0)
uint16_t bit = 1 << verification.quorum_index;
if ((block.pulse.validator_participation_bits & bit) == 0)
{
LOG_PRINT_L1("Received pulse signature from validator " << static_cast<int>(verification.quorum_index) << " that is not participating in round " << static_cast<int>(block.pulse.round) << "\n" << dump_pulse_block_data(block, quorum.get()));
return false;

View File

@ -5,9 +5,11 @@
#include "service_node_voting.h"
namespace service_nodes {
constexpr size_t PULSE_QUORUM_ENTROPY_LAG = 21; // How many blocks back from the tip of the Blockchain to source entropy for the Pulse quorums.
constexpr size_t PULSE_QUORUM_SIZE = 11;
constexpr size_t PULSE_BLOCK_REQUIRED_SIGNATURES = 7; // A block must have exactly N signatures to be considered properly
constexpr size_t PULSE_QUORUM_ENTROPY_LAG = 21; // How many blocks back from the tip of the Blockchain to source entropy for the Pulse quorums.
constexpr size_t PULSE_QUORUM_SIZE = 11;
constexpr size_t PULSE_BLOCK_REQUIRED_SIGNATURES = 7; // A block must have exactly N signatures to be considered properly
constexpr size_t PULSE_MIN_SERVICE_NODES = PULSE_QUORUM_SIZE + 1 /*Leader*/;
constexpr uint16_t PULSE_VALIDATOR_PARTICIPATION_MASK = 0b0000'0111'1111'1111; // A quorum size of 11,
static_assert(PULSE_QUORUM_SIZE >= PULSE_BLOCK_REQUIRED_SIGNATURES, "Quorum must be larger than the required number of signatures.");
static_assert(PULSE_QUORUM_ENTROPY_LAG >= PULSE_QUORUM_SIZE, "We need to pull atleast PULSE_QUORUM_SIZE number of blocks from the Blockchain, we can't if the amount of blocks to go back from the tip of the Blockchain is less than the blocks we need.");