mirror of https://github.com/oxen-io/oxen-core.git
Code review, keep nonce, remove HF_VERSION..
- Keep none for blocks - Remove HF_VERSION_PULSE and prefer network_version_16 for big features - Keep HF_VERSION_... for smaller feature flags - Add operator< for pulse_sort_key - Avoid erase() in validators gen loop for pulse
This commit is contained in:
parent
5a49e03ebf
commit
ae29ecb335
|
@ -443,10 +443,9 @@ namespace cryptonote
|
|||
VARINT_FIELD(minor_version)
|
||||
VARINT_FIELD(timestamp)
|
||||
FIELD(prev_id)
|
||||
if (major_version >= HF_VERSION_PULSE)
|
||||
FIELD(nonce)
|
||||
if (major_version >= cryptonote::network_version_16)
|
||||
FIELD(pulse)
|
||||
else
|
||||
FIELD(nonce)
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
|
|
|
@ -172,7 +172,6 @@ static_assert(STAKING_PORTIONS % 12 == 0, "Use a multiple of twelve, so that it
|
|||
#define HF_VERSION_REJECT_SIGS_IN_COINBASE cryptonote::network_version_16
|
||||
#define HF_VERSION_ENFORCE_MIN_AGE cryptonote::network_version_16
|
||||
#define HF_VERSION_EFFECTIVE_SHORT_TERM_MEDIAN_IN_PENALTY cryptonote::network_version_16
|
||||
#define HF_VERSION_PULSE cryptonote::network_version_16
|
||||
|
||||
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8
|
||||
|
||||
|
|
|
@ -1363,31 +1363,18 @@ namespace service_nodes
|
|||
((uint64_t)pulse_round & 0xFF) << 40 |
|
||||
((uint64_t)pulse_round & 0xFF) << 48 |
|
||||
((uint64_t)pulse_round & 0xFF) << 56;
|
||||
if (block.major_version >= HF_VERSION_PULSE)
|
||||
if (block.major_version >= cryptonote::network_version_16)
|
||||
{
|
||||
uint64_t random_value_xored[2];
|
||||
static_assert(sizeof(block.pulse.random_value) == sizeof(random_value_xored), "Expected 16 byte size");
|
||||
|
||||
memcpy(&random_value_xored[0], block.pulse.random_value.data, sizeof(random_value_xored[0]));
|
||||
memcpy(&random_value_xored[1], block.pulse.random_value.data + sizeof(random_value_xored[0]), sizeof(random_value_xored[1]));
|
||||
|
||||
random_value_xored[0] ^= xor64;
|
||||
random_value_xored[1] ^= xor64;
|
||||
crypto::cn_fast_hash(random_value_xored, sizeof(random_value_xored), hash.data);
|
||||
std::array<uint8_t, 1 + sizeof(block.pulse.random_value)> src = {pulse_round};
|
||||
std::copy(std::begin(block.pulse.random_value.data), std::end(block.pulse.random_value.data), src.begin() + 1);
|
||||
crypto::cn_fast_hash(src.data(), src.size(), hash.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
crypto::hash xor_hash;
|
||||
static_assert(sizeof(xor_hash) % sizeof(xor64) == 0, "We want to construct a hash composed of the xor value");
|
||||
|
||||
for (size_t i = 0; i < sizeof(xor_hash) / sizeof(xor64); i++)
|
||||
{
|
||||
char *dest = xor_hash.data + (i * sizeof(xor64));
|
||||
memcpy(dest, &xor64, sizeof(xor64));
|
||||
}
|
||||
|
||||
hash = cryptonote::get_block_hash(block);
|
||||
crypto::hash_xor(hash, xor_hash);
|
||||
crypto::hash block_hash = cryptonote::get_block_hash(block);
|
||||
std::array<uint8_t, 1 + sizeof(hash)> src = {pulse_round};
|
||||
std::copy(std::begin(block_hash.data), std::end(block_hash.data), src.begin() + 1);
|
||||
crypto::cn_fast_hash(src.data(), src.size(), hash.data);
|
||||
}
|
||||
|
||||
assert(hash != crypto::null_hash);
|
||||
|
@ -1522,57 +1509,46 @@ namespace service_nodes
|
|||
continue;
|
||||
}
|
||||
|
||||
// NOTE: Find the leader for this block
|
||||
block_winner winner = state.get_block_winner();
|
||||
quorum->workers.push_back(winner.key);
|
||||
|
||||
std::vector<pubkey_and_sninfo const *> pulse_candidates;
|
||||
pulse_candidates.reserve(active_snode_list.size());
|
||||
|
||||
// TODO(doyle): Support leaders failing and iterating the round for this block.
|
||||
// NOTE: Find the leader for this block
|
||||
for (auto &node : active_snode_list)
|
||||
{
|
||||
auto best_leader_index = static_cast<size_t>(-1);
|
||||
auto best_reward_time = std::make_pair(static_cast<uint64_t>(-1), static_cast<uint32_t>(-1));
|
||||
for (size_t node_index = 0; node_index < active_snode_list.size(); node_index++)
|
||||
{
|
||||
pubkey_and_sninfo const &node = active_snode_list[node_index];
|
||||
auto reward_time = std::make_pair(node.second->last_reward_block_height, node.second->last_reward_transaction_index);
|
||||
if (reward_time < best_reward_time)
|
||||
{
|
||||
best_reward_time = reward_time;
|
||||
best_leader_index = node_index;
|
||||
}
|
||||
|
||||
if (node.first != winner.key)
|
||||
pulse_candidates.push_back(&node);
|
||||
}
|
||||
|
||||
quorum->workers.push_back(pulse_candidates[best_leader_index]->first);
|
||||
pulse_candidates.erase(pulse_candidates.begin() + best_leader_index);
|
||||
}
|
||||
|
||||
// NOTE: Sort ascending in height i.e. sort preferring the longest time since the validator was in a Pulse quorum.
|
||||
std::stable_sort(pulse_candidates.begin(), pulse_candidates.end(), [](pubkey_and_sninfo const *a, pubkey_and_sninfo const *b) {
|
||||
auto a_key = std::make_pair(a->second->pulse_sort_key.last_height_validating_in_quorum, a->second->pulse_sort_key.quorum_index);
|
||||
auto b_key = std::make_pair(b->second->pulse_sort_key.last_height_validating_in_quorum, b->second->pulse_sort_key.quorum_index);
|
||||
bool result = a_key < b_key;
|
||||
bool result = a->second->pulse_sorter < b->second->pulse_sorter;
|
||||
return result;
|
||||
});
|
||||
|
||||
// NOTE: Divide the list in half, select validators from the first half of the list.
|
||||
// Remove them from the list of candidates once chosen.
|
||||
size_t const midpoint = pulse_candidates.size() / 2;
|
||||
for (size_t i = 0; i < pulse_entropy.size(); i++)
|
||||
// Swap the chosen validator into first half of the list.
|
||||
auto running_it = pulse_candidates.begin();
|
||||
size_t const partition_index = pulse_candidates.size() / 2;
|
||||
for (crypto::hash const &entropy : pulse_entropy)
|
||||
{
|
||||
size_t const partition_index = std::min(midpoint, pulse_candidates.size());
|
||||
std::mt19937_64 rng(quorum_rng_seed(pulse_entropy[i], type));
|
||||
size_t candidate_index = tools::uniform_distribution_portable(rng, partition_index);
|
||||
pubkey_and_sninfo const *candidate = pulse_candidates[candidate_index];
|
||||
std::mt19937_64 rng(quorum_rng_seed(entropy, type));
|
||||
size_t candidate_index = tools::uniform_distribution_portable(rng, partition_index - std::distance(pulse_candidates.begin(), running_it));
|
||||
std::swap(*running_it, *(pulse_candidates.begin() + candidate_index));
|
||||
running_it++;
|
||||
}
|
||||
|
||||
quorum->validators.push_back(candidate->first);
|
||||
pulse_candidates.erase(pulse_candidates.begin() + candidate_index);
|
||||
for (auto it = pulse_candidates.begin(); it != running_it; it++)
|
||||
{
|
||||
crypto::public_key const &validator_key = (*it)->first;
|
||||
quorum->validators.push_back(validator_key);
|
||||
|
||||
// NOTE: Send candidate to the back of the list
|
||||
auto &info_ptr = state.service_nodes_infos.at(candidate->first);
|
||||
auto &info_ptr = state.service_nodes_infos.at(validator_key);
|
||||
service_node_info &new_info = duplicate_info(info_ptr);
|
||||
new_info.pulse_sort_key.last_height_validating_in_quorum = state.height;
|
||||
new_info.pulse_sort_key.quorum_index = quorum->validators.size() - 1;
|
||||
new_info.pulse_sorter.last_height_validating_in_quorum = state.height;
|
||||
new_info.pulse_sorter.quorum_index = quorum->validators.size() - 1;
|
||||
}
|
||||
|
||||
result.pulse = quorum;
|
||||
|
@ -1699,7 +1675,7 @@ namespace service_nodes
|
|||
|
||||
// TODO(doyle): Error handling, we assume it works
|
||||
std::vector<crypto::hash> entropy;
|
||||
if (hf_version >= HF_VERSION_PULSE) get_pulse_entropy_from_blockchain(db, entropy, 0 /*pulse_round*/);
|
||||
if (hf_version >= cryptonote::network_version_16) get_pulse_entropy_from_blockchain(db, entropy, 0 /*pulse_round*/);
|
||||
quorums = generate_quorums(*this, active_snode_list, nettype, hf_version, entropy);
|
||||
}
|
||||
|
||||
|
@ -2544,7 +2520,7 @@ namespace service_nodes
|
|||
else
|
||||
info.recommission_credit = 0;
|
||||
|
||||
info.pulse_sort_key.last_height_validating_in_quorum = info.last_reward_block_height;
|
||||
info.pulse_sorter.last_height_validating_in_quorum = info.last_reward_block_height;
|
||||
info.version = version_t::v5_pulse_recomm_credit;
|
||||
}
|
||||
// Make sure we handled any future state version upgrades:
|
||||
|
|
|
@ -98,14 +98,20 @@ namespace service_nodes
|
|||
void store(const crypto::public_key &pubkey, cryptonote::Blockchain &blockchain);
|
||||
};
|
||||
|
||||
struct pulse_sort_key_t
|
||||
struct pulse_sort_key
|
||||
{
|
||||
uint64_t last_height_validating_in_quorum = 0;
|
||||
uint8_t quorum_index = 0;
|
||||
uint8_t quorum_index = 0;
|
||||
|
||||
bool operator<(pulse_sort_key const &other) const
|
||||
{
|
||||
bool result = std::make_pair(last_height_validating_in_quorum, quorum_index) < std::make_pair(other.last_height_validating_in_quorum, other.quorum_index);
|
||||
return result;
|
||||
}
|
||||
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
VARINT_FIELD(last_height_validating_in_quorum)
|
||||
VARINT_FIELD(quorum_index)
|
||||
FIELD(quorum_index)
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
|
@ -191,7 +197,7 @@ namespace service_nodes
|
|||
uint64_t last_ip_change_height = 0; // The height of the last quorum penalty for changing IPs
|
||||
version_t version = tools::enum_top<version_t>;
|
||||
uint8_t registration_hf_version = 0;
|
||||
pulse_sort_key_t pulse_sort_key;
|
||||
pulse_sort_key pulse_sorter;
|
||||
|
||||
service_node_info() = default;
|
||||
bool is_fully_funded() const { return total_contributed >= staking_requirement; }
|
||||
|
@ -238,7 +244,7 @@ namespace service_nodes
|
|||
if (version >= version_t::v5_pulse_recomm_credit)
|
||||
{
|
||||
VARINT_FIELD(recommission_credit)
|
||||
FIELD(pulse_sort_key);
|
||||
FIELD(pulse_sorter)
|
||||
}
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
|
|
@ -191,7 +191,7 @@ namespace service_nodes {
|
|||
return
|
||||
hf_version <= cryptonote::network_version_12_checkpointing ? quorum_type::obligations :
|
||||
hf_version < cryptonote::network_version_14_blink ? quorum_type::checkpointing :
|
||||
hf_version < HF_VERSION_PULSE ? quorum_type::blink :
|
||||
hf_version < cryptonote::network_version_16 ? quorum_type::blink :
|
||||
quorum_type::pulse;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue