mirror of https://github.com/oxen-io/oxen-core.git
Pulse: Rename participation to validator_bitset
This commit is contained in:
parent
72e57be95f
commit
601e9f77e1
|
@ -436,14 +436,14 @@ namespace cryptonote
|
|||
|
||||
struct pulse_header
|
||||
{
|
||||
pulse_random_value random_value;
|
||||
uint8_t round;
|
||||
uint16_t validator_participation_bits;
|
||||
pulse_random_value random_value;
|
||||
uint8_t round;
|
||||
uint16_t validator_bitset;
|
||||
|
||||
BEGIN_SERIALIZE()
|
||||
FIELD(random_value);
|
||||
FIELD(round);
|
||||
FIELD(validator_participation_bits);
|
||||
FIELD(validator_bitset);
|
||||
END_SERIALIZE();
|
||||
};
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ enum struct round_state
|
|||
wait_for_round,
|
||||
round_starts,
|
||||
wait_for_handshakes,
|
||||
wait_for_other_validator_handshake_bitsets,
|
||||
wait_for_handshake_bitsets,
|
||||
submit_block_template,
|
||||
wait_for_block_template,
|
||||
terminate,
|
||||
|
@ -32,7 +32,7 @@ constexpr std::string_view round_state_string(round_state state)
|
|||
case round_state::wait_for_round: return "Wait For Round"sv;
|
||||
case round_state::round_starts: return "Round Starts"sv;
|
||||
case round_state::wait_for_handshakes: return "Wait For Handshakes"sv;
|
||||
case round_state::wait_for_other_validator_handshake_bitsets: return "Wait For Validator Handshake Bitsets"sv;
|
||||
case round_state::wait_for_handshake_bitsets: return "Wait For Validator Handshake Bitsets"sv;
|
||||
case round_state::submit_block_template: return "Submit Block Template"sv;
|
||||
case round_state::wait_for_block_template: return "Wait For Block Template"sv;
|
||||
case round_state::terminate: return "Terminate"sv;
|
||||
|
@ -69,11 +69,11 @@ struct round_context
|
|||
|
||||
struct
|
||||
{
|
||||
std::array<uint16_t, service_nodes::PULSE_QUORUM_NUM_VALIDATORS> received_bitsets;
|
||||
int received_bitsets_count;
|
||||
std::array<uint16_t, service_nodes::PULSE_QUORUM_NUM_VALIDATORS> bitsets;
|
||||
int bitsets_count;
|
||||
pulse::time_point end_time;
|
||||
bool all_received() { return received_bitsets_count == service_nodes::PULSE_QUORUM_NUM_VALIDATORS; }
|
||||
} wait_for_other_validator_handshake_bitsets;
|
||||
bool all_received() { return bitsets_count == service_nodes::PULSE_QUORUM_NUM_VALIDATORS; }
|
||||
} wait_for_handshake_bitsets;
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -325,8 +325,8 @@ void pump_messages_from_quorumnet(void *quorumnet_state, round_state round_state
|
|||
pump_messages_until = context.wait_for_handshakes.end_time;
|
||||
break;
|
||||
|
||||
case round_state::wait_for_other_validator_handshake_bitsets:
|
||||
pump_messages_until = context.wait_for_other_validator_handshake_bitsets.end_time;
|
||||
case round_state::wait_for_handshake_bitsets:
|
||||
pump_messages_until = context.wait_for_handshake_bitsets.end_time;
|
||||
break;
|
||||
|
||||
case round_state::wait_for_block_template:
|
||||
|
@ -405,18 +405,18 @@ void pump_messages_from_quorumnet(void *quorumnet_state, round_state round_state
|
|||
|
||||
case pulse::message_type::handshake_bitset:
|
||||
{
|
||||
if (!msg_time_check(pulse_height, context, msg, pulse::clock::now(), context.wait_for_handshakes.start_time, context.wait_for_other_validator_handshake_bitsets.end_time))
|
||||
if (!msg_time_check(pulse_height, context, msg, pulse::clock::now(), context.wait_for_handshakes.start_time, context.wait_for_handshake_bitsets.end_time))
|
||||
continue;
|
||||
|
||||
uint16_t prev_bitset = context.wait_for_other_validator_handshake_bitsets.received_bitsets[msg.handshakes.quorum_position];
|
||||
uint16_t prev_bitset = context.wait_for_handshake_bitsets.bitsets[msg.handshakes.quorum_position];
|
||||
if (!context.round_starts.is_producer)
|
||||
relay_message = (prev_bitset != msg.handshakes.validator_bitset);
|
||||
|
||||
context.wait_for_other_validator_handshake_bitsets.received_bitsets[msg.handshakes.quorum_position] = msg.handshakes.validator_bitset;
|
||||
context.wait_for_handshake_bitsets.bitsets[msg.handshakes.quorum_position] = msg.handshakes.validator_bitset;
|
||||
if (prev_bitset == 0)
|
||||
context.wait_for_other_validator_handshake_bitsets.received_bitsets_count++;
|
||||
context.wait_for_handshake_bitsets.bitsets_count++;
|
||||
|
||||
finish_pumping = context.wait_for_other_validator_handshake_bitsets.all_received();
|
||||
finish_pumping = context.wait_for_handshake_bitsets.all_received();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -449,10 +449,10 @@ void pump_messages_from_quorumnet(void *quorumnet_state, round_state round_state
|
|||
continue;
|
||||
}
|
||||
|
||||
if (block.pulse.validator_participation_bits != context.submit_block_template.validator_bitset)
|
||||
if (block.pulse.validator_bitset != context.submit_block_template.validator_bitset)
|
||||
{
|
||||
auto block_bitset = std::bitset<sizeof(block.pulse.validator_participation_bits) * 8>(block.pulse.validator_participation_bits);
|
||||
auto our_bitset = std::bitset<sizeof(block.pulse.validator_participation_bits) * 8>(context.submit_block_template.validator_bitset);
|
||||
auto block_bitset = std::bitset<sizeof(block.pulse.validator_bitset) * 8>(block.pulse.validator_bitset);
|
||||
auto our_bitset = std::bitset<sizeof(block.pulse.validator_bitset) * 8>(context.submit_block_template.validator_bitset);
|
||||
MGINFO(log_prefix(pulse_height, context) << "Received pulse block template specifying different validator handshake bitsets " << block_bitset << ", expected " << our_bitset);
|
||||
continue;
|
||||
}
|
||||
|
@ -595,8 +595,8 @@ void pulse::main(pulse::state &state, void *quorumnet_state, cryptonote::core &c
|
|||
pulse::time_point const start_time = context.wait_next_block.round_0_start_time +
|
||||
(context.wait_next_block.round * service_nodes::PULSE_TIME_PER_BLOCK);
|
||||
context.wait_for_handshakes.end_time = start_time + service_nodes::PULSE_WAIT_FOR_HANDSHAKES_DURATION;
|
||||
context.wait_for_other_validator_handshake_bitsets.end_time = context.wait_for_handshakes.end_time + service_nodes::PULSE_WAIT_FOR_OTHER_VALIDATOR_HANDSHAKES_DURATION;
|
||||
context.wait_for_block_template.end_time = context.wait_for_other_validator_handshake_bitsets.end_time + service_nodes::PULSE_WAIT_FOR_BLOCK_TEMPLATE_DURATION;
|
||||
context.wait_for_handshake_bitsets.end_time = context.wait_for_handshakes.end_time + service_nodes::PULSE_WAIT_FOR_OTHER_VALIDATOR_HANDSHAKES_DURATION;
|
||||
context.wait_for_block_template.end_time = context.wait_for_handshake_bitsets.end_time + service_nodes::PULSE_WAIT_FOR_BLOCK_TEMPLATE_DURATION;
|
||||
|
||||
//
|
||||
// NOTE: Quorum
|
||||
|
@ -674,7 +674,7 @@ void pulse::main(pulse::state &state, void *quorumnet_state, cryptonote::core &c
|
|||
{
|
||||
context.round_starts.node_name = "W[0]";
|
||||
MGINFO(log_prefix(pulse_height, context) << "We are the block producer for height " << pulse_height << " in round " << +context.wait_next_block.round << ", awaiting validator handshake bitsets.");
|
||||
round_state = round_state::wait_for_other_validator_handshake_bitsets;
|
||||
round_state = round_state::wait_for_handshake_bitsets;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -689,42 +689,42 @@ void pulse::main(pulse::state &state, void *quorumnet_state, cryptonote::core &c
|
|||
case round_state::wait_for_handshakes:
|
||||
{
|
||||
assert(!context.round_starts.is_producer);
|
||||
assert(context.round_starts.my_quorum_position < context.wait_for_other_validator_handshake_bitsets.received_bitsets.size());
|
||||
assert(context.round_starts.my_quorum_position < context.wait_for_handshake_bitsets.bitsets.size());
|
||||
|
||||
bool timed_out = pulse::clock::now() >= context.wait_for_handshakes.end_time;
|
||||
bool all_handshakes = context.wait_for_handshakes.all_received();
|
||||
|
||||
if (all_handshakes || timed_out)
|
||||
{
|
||||
assert(context.round_starts.my_quorum_position < context.wait_for_other_validator_handshake_bitsets.received_bitsets.size());
|
||||
assert(context.round_starts.my_quorum_position < context.wait_for_handshake_bitsets.bitsets.size());
|
||||
std::bitset<8 * sizeof(context.wait_for_handshakes.validator_bits)> bitset = context.wait_for_handshakes.validator_bits;
|
||||
|
||||
context.wait_for_other_validator_handshake_bitsets.received_bitsets[context.round_starts.my_quorum_position] = context.wait_for_handshakes.validator_bits;
|
||||
context.wait_for_other_validator_handshake_bitsets.received_bitsets_count++;
|
||||
context.wait_for_handshake_bitsets.bitsets[context.round_starts.my_quorum_position] = context.wait_for_handshakes.validator_bits;
|
||||
context.wait_for_handshake_bitsets.bitsets_count++;
|
||||
|
||||
bool missing_handshakes = timed_out && !all_handshakes;
|
||||
MGINFO(log_prefix(pulse_height, context) << "Collected validator handshakes " << bitset << (missing_handshakes ? ", we timed out and some handshakes were not seen! " : ". ") << "Sending handshake bitset and collecting other validator bitsets.");
|
||||
try
|
||||
{
|
||||
cryptonote::quorumnet_send_pulse_validator_handshake_bitset(quorumnet_state, context.wait_for_round.quorum, top_hash, context.wait_for_handshakes.validator_bits);
|
||||
round_state = round_state::wait_for_other_validator_handshake_bitsets;
|
||||
round_state = round_state::wait_for_handshake_bitsets;
|
||||
}
|
||||
catch(std::exception const &e)
|
||||
{
|
||||
MERROR(log_prefix(pulse_height, context) << "Attempting to invoke and send a Pulse participation handshake bitset unexpectedly failed. " << e.what());
|
||||
MERROR(log_prefix(pulse_height, context) << "Attempting to invoke and send a Pulse validator bitset unexpectedly failed. " << e.what());
|
||||
round_state = thread_sleep(sleep_until::next_block_or_round, state, blockchain, context, pulse_mutex, pulse_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case round_state::wait_for_other_validator_handshake_bitsets:
|
||||
case round_state::wait_for_handshake_bitsets:
|
||||
{
|
||||
size_t const max_bitsets = context.wait_for_other_validator_handshake_bitsets.received_bitsets.size();
|
||||
size_t const bitsets_count = context.wait_for_other_validator_handshake_bitsets.received_bitsets_count;
|
||||
size_t const max_bitsets = context.wait_for_handshake_bitsets.bitsets.size();
|
||||
size_t const bitsets_count = context.wait_for_handshake_bitsets.bitsets_count;
|
||||
|
||||
bool all_bitsets = context.wait_for_other_validator_handshake_bitsets.all_received();
|
||||
bool timed_out = pulse::clock::now() >= context.wait_for_other_validator_handshake_bitsets.end_time;
|
||||
bool all_bitsets = context.wait_for_handshake_bitsets.all_received();
|
||||
bool timed_out = pulse::clock::now() >= context.wait_for_handshake_bitsets.end_time;
|
||||
if (timed_out || all_bitsets)
|
||||
{
|
||||
bool missing_bitsets = timed_out && !all_bitsets;
|
||||
|
@ -737,7 +737,7 @@ void pulse::main(pulse::state &state, void *quorumnet_state, cryptonote::core &c
|
|||
int count = 0;
|
||||
for (size_t validator_index = 0; validator_index < max_bitsets; validator_index++)
|
||||
{
|
||||
uint16_t bits = context.wait_for_other_validator_handshake_bitsets.received_bitsets[validator_index];
|
||||
uint16_t bits = context.wait_for_handshake_bitsets.bitsets[validator_index];
|
||||
uint16_t num = ++most_common_validator_bitset[bits];
|
||||
if (num > count)
|
||||
{
|
||||
|
@ -810,8 +810,8 @@ void pulse::main(pulse::state &state, void *quorumnet_state, cryptonote::core &c
|
|||
uint64_t expected_reward = 0;
|
||||
blockchain.create_next_pulse_block_template(block, block_producer_payouts, pulse_height, expected_reward);
|
||||
|
||||
block.pulse.round = context.wait_next_block.round;
|
||||
block.pulse.validator_participation_bits = context.submit_block_template.validator_bitset;
|
||||
block.pulse.round = context.wait_next_block.round;
|
||||
block.pulse.validator_bitset = context.submit_block_template.validator_bitset;
|
||||
|
||||
std::string block_blob = cryptonote::t_serializable_object_to_blob(block);
|
||||
crypto::hash hash = crypto::cn_fast_hash(block_blob.data(), block_blob.size());
|
||||
|
@ -826,6 +826,7 @@ void pulse::main(pulse::state &state, void *quorumnet_state, cryptonote::core &c
|
|||
|
||||
case round_state::wait_for_block_template:
|
||||
{
|
||||
assert(!context.round_starts.is_producer);
|
||||
bool timed_out = pulse::clock::now() >= context.wait_for_block_template.end_time;
|
||||
if (timed_out || context.wait_for_block_template.received)
|
||||
{
|
||||
|
|
|
@ -1242,13 +1242,13 @@ namespace service_nodes
|
|||
static std::string dump_pulse_block_data(cryptonote::block const &block, service_nodes::quorum const *quorum)
|
||||
{
|
||||
std::stringstream stream;
|
||||
std::bitset<8 * sizeof(block.pulse.validator_participation_bits)> const participation_bits = block.pulse.validator_participation_bits;
|
||||
std::bitset<8 * sizeof(block.pulse.validator_bitset)> const validator_bitset = block.pulse.validator_bitset;
|
||||
stream << "Block(" << cryptonote::get_block_height(block) << "): " << cryptonote::get_block_hash(block) << "\n";
|
||||
stream << "Leader: ";
|
||||
if (quorum) stream << (quorum->workers.empty() ? "(invalid leader)" : lokimq::to_hex(tools::view_guts(quorum->workers[0]))) << "\n";
|
||||
else stream << "(invalid quorum)\n";
|
||||
stream << "Round: " << +block.pulse.round << "\n";
|
||||
stream << "Participating Validators: " << participation_bits << "\n";
|
||||
stream << "Validator Bitset: " << validator_bitset << "\n";
|
||||
|
||||
stream << "Signatures: ";
|
||||
if (block.signatures.empty()) stream << "(none)";
|
||||
|
@ -1287,10 +1287,10 @@ namespace service_nodes
|
|||
return false;
|
||||
}
|
||||
|
||||
if (block.pulse.validator_participation_bits >= (1 << PULSE_QUORUM_NUM_VALIDATORS))
|
||||
if (block.pulse.validator_bitset >= (1 << PULSE_QUORUM_NUM_VALIDATORS))
|
||||
{
|
||||
auto mask = std::bitset<sizeof(pulse_validator_bit_mask()) * 8>(pulse_validator_bit_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()));
|
||||
LOG_PRINT_L1("Pulse block specifies validator bitset out of bounds. Expected the bit mask " << mask << "\n" << dump_pulse_block_data(block, quorum.get()));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1307,7 +1307,7 @@ namespace service_nodes
|
|||
}
|
||||
else
|
||||
{
|
||||
bool expect_pulse_quorum = (block.pulse.validator_participation_bits > 0 || block.signatures.size());
|
||||
bool expect_pulse_quorum = (block.pulse.validator_bitset > 0 || block.signatures.size());
|
||||
if (expect_pulse_quorum)
|
||||
{
|
||||
LOG_PRINT_L1("Failed to get pulse quorum for block\n" << dump_pulse_block_data(block, quorum.get()));
|
||||
|
|
|
@ -270,7 +270,7 @@ namespace service_nodes
|
|||
}
|
||||
|
||||
auto const &block = reinterpret_cast<cryptonote::block const &>(context);
|
||||
if (block.pulse.validator_participation_bits >= (1 << PULSE_QUORUM_NUM_VALIDATORS))
|
||||
if (block.pulse.validator_bitset >= (1 << PULSE_QUORUM_NUM_VALIDATORS))
|
||||
{
|
||||
auto mask = std::bitset<sizeof(pulse_validator_bit_mask()) * 8>(pulse_validator_bit_mask());
|
||||
LOG_PRINT_L1("Pulse block specifies validator participation bits out of bounds. Expected the bit mask: " << mask);
|
||||
|
@ -304,7 +304,7 @@ namespace service_nodes
|
|||
{
|
||||
auto const block = std::any_cast<cryptonote::block const &>(context);
|
||||
uint16_t bit = 1 << quorum_signature.voter_index;
|
||||
if ((block.pulse.validator_participation_bits & bit) == 0)
|
||||
if ((block.pulse.validator_bitset & bit) == 0)
|
||||
{
|
||||
LOG_PRINT_L1("Received pulse signature from validator " << static_cast<int>(quorum_signature.voter_index) << " that is not participating in round " << static_cast<int>(block.pulse.round));
|
||||
return false;
|
||||
|
|
|
@ -812,7 +812,7 @@ bool loki_chain_generator::block_begin(loki_blockchain_entry &entry, loki_create
|
|||
if (make_pulse_block)
|
||||
{
|
||||
// NOTE: Set up Pulse Header
|
||||
blk.pulse.validator_participation_bits = service_nodes::pulse_validator_bit_mask(); // NOTE: Everyone participates
|
||||
blk.pulse.validator_bitset = service_nodes::pulse_validator_bit_mask(); // NOTE: Everyone participates
|
||||
blk.pulse.round = params.pulse_round;
|
||||
for (size_t i = 0; i < sizeof(blk.pulse.random_value.data); i++)
|
||||
blk.pulse.random_value.data[i] = static_cast<char>(tools::uniform_distribution_portable(tools::rng, 256));
|
||||
|
|
|
@ -148,7 +148,7 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(loki_service_nodes_insufficient_contribution);
|
||||
GENERATE_AND_PLAY(loki_service_nodes_test_rollback);
|
||||
GENERATE_AND_PLAY(loki_service_nodes_test_swarms_basic);
|
||||
GENERATE_AND_PLAY(loki_pulse_invalid_participation_bits);
|
||||
GENERATE_AND_PLAY(loki_pulse_invalid_validator_bitset);
|
||||
GENERATE_AND_PLAY(loki_pulse_invalid_signature);
|
||||
GENERATE_AND_PLAY(loki_pulse_oob_voter_index);
|
||||
GENERATE_AND_PLAY(loki_pulse_non_participating_validator);
|
||||
|
|
|
@ -3051,19 +3051,19 @@ static loki_chain_generator setup_pulse_tests(std::vector<test_event_entry> &eve
|
|||
return result;
|
||||
}
|
||||
|
||||
bool loki_pulse_invalid_participation_bits::generate(std::vector<test_event_entry> &events)
|
||||
bool loki_pulse_invalid_validator_bitset::generate(std::vector<test_event_entry> &events)
|
||||
{
|
||||
loki_chain_generator gen = setup_pulse_tests(events);
|
||||
gen.add_event_msg("Invalid Block: Participation bits wrong");
|
||||
gen.add_event_msg("Invalid Block: Validator bitset wrong");
|
||||
loki_blockchain_entry entry = {};
|
||||
loki_create_block_params params = gen.next_block_params();
|
||||
gen.block_begin(entry, params, {} /*tx_list*/);
|
||||
|
||||
// NOTE: Overwrite participation bits to be wrong
|
||||
entry.block.pulse.validator_participation_bits = ~service_nodes::pulse_validator_bit_mask();
|
||||
// NOTE: Overwrite valiadator bitset to be wrong
|
||||
entry.block.pulse.validator_bitset = ~service_nodes::pulse_validator_bit_mask();
|
||||
|
||||
gen.block_end(entry, params);
|
||||
gen.add_block(entry, false /*can_be_added_to_blockchain*/, "Invalid Pulse Block, specifies the wrong participation bits");
|
||||
gen.add_block(entry, false /*can_be_added_to_blockchain*/, "Invalid Pulse Block, specifies the wrong validator bitset");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3079,7 +3079,7 @@ bool loki_pulse_invalid_signature::generate(std::vector<test_event_entry> &event
|
|||
// NOTE: Overwrite signature
|
||||
entry.block.signatures[0].signature = {};
|
||||
gen.block_end(entry, params);
|
||||
gen.add_block(entry, false /*can_be_added_to_blockchain*/, "Invalid Pulse Block, specifies the wrong participation bits");
|
||||
gen.add_block(entry, false /*can_be_added_to_blockchain*/, "Invalid Pulse Block, specifies the wrong validator bitset");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3095,7 +3095,7 @@ bool loki_pulse_oob_voter_index::generate(std::vector<test_event_entry> &events)
|
|||
// NOTE: Overwrite oob voter index
|
||||
entry.block.signatures.back().voter_index = service_nodes::PULSE_QUORUM_NUM_VALIDATORS + 1;
|
||||
gen.block_end(entry, params);
|
||||
gen.add_block(entry, false /*can_be_added_to_blockchain*/, "Invalid Pulse Block, specifies the wrong participation bits");
|
||||
gen.add_block(entry, false /*can_be_added_to_blockchain*/, "Invalid Pulse Block, specifies the wrong validator bitset");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3130,8 +3130,8 @@ bool loki_pulse_non_participating_validator::generate(std::vector<test_event_ent
|
|||
// NOTE: First 7 validators are locked in. We received signatures from the
|
||||
// first 6 in the quorum, then the 8th validator in the quorum (who is not
|
||||
// meant to be participating).
|
||||
entry.block.pulse.validator_participation_bits = 0b0000'000'0111'1111;
|
||||
size_t const voter_indexes[] = {0, 1, 2, 3, 4, 5, 7};
|
||||
entry.block.pulse.validator_bitset = 0b0000'000'0111'1111;
|
||||
size_t const voter_indexes[] = {0, 1, 2, 3, 4, 5, 7};
|
||||
|
||||
crypto::hash block_hash = cryptonote::get_block_hash(entry.block);
|
||||
for (size_t index : voter_indexes)
|
||||
|
@ -3147,7 +3147,7 @@ bool loki_pulse_non_participating_validator::generate(std::vector<test_event_ent
|
|||
}
|
||||
|
||||
gen.block_end(entry, params);
|
||||
gen.add_block(entry, false /*can_be_added_to_blockchain*/, "Invalid Pulse Block, specifies the wrong participation bits");
|
||||
gen.add_block(entry, false /*can_be_added_to_blockchain*/, "Invalid Pulse Block, specifies the wrong validator bitset");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ struct loki_service_nodes_gen_nodes
|
|||
struct loki_service_nodes_insufficient_contribution : public test_chain_unit_base { bool generate(std::vector<test_event_entry>& events); };
|
||||
struct loki_service_nodes_test_rollback : public test_chain_unit_base { bool generate(std::vector<test_event_entry>& events); };
|
||||
struct loki_service_nodes_test_swarms_basic : public test_chain_unit_base { bool generate(std::vector<test_event_entry>& events); };
|
||||
struct loki_pulse_invalid_participation_bits : public test_chain_unit_base { bool generate(std::vector<test_event_entry>& events); };
|
||||
struct loki_pulse_invalid_validator_bitset : public test_chain_unit_base { bool generate(std::vector<test_event_entry>& events); };
|
||||
struct loki_pulse_invalid_signature : public test_chain_unit_base { bool generate(std::vector<test_event_entry>& events); };
|
||||
struct loki_pulse_oob_voter_index : public test_chain_unit_base { bool generate(std::vector<test_event_entry>& events); };
|
||||
struct loki_pulse_non_participating_validator : public test_chain_unit_base { bool generate(std::vector<test_event_entry>& events); };
|
||||
|
|
Loading…
Reference in New Issue